How D
  • 板块学术版
  • 楼主tallnut
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/4/6 21:52
  • 上次更新2024/4/7 13:10:25
查看原帖
How D
1037586
tallnut楼主2024/4/6 21:52

思路:对于每个药物点,跑一遍bfs,看他在不吃任何其他药的情况下能达到哪些其他药物点。这就连成了一个图论网络,最后从起始点再来一次bfs,判断从起始点能否通过这个图论网络到达终点。

时间复杂度 Θ(nm2)\Theta(nm^2),但是为什么T了一堆而且被教练制裁呢?

代码:

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cctype>
#include <bitset>
#pragma GCC optimize("O3","Ofast","unroll-loops")
using namespace std;
const int N = 305,M = 205;
int h,w,n,begx,begy,endx,endy,tmp2;
char cc;
//type:1=通路,0=障碍物
bool a[M][M];
//把药物点标记出来
int mp[M][M];
int r[N],c[N],e[N];
//表示每个药物点可以到哪些其他药物点,如果可以到终点就存一个n+1
vector<int> v[N];
struct point
{
	int x;
	int y;
	int energy;
} tmp;
bool visited[M][M];
bitset<N> visited2;
namespace tallnut{void qread(int&x){char c=getchar();bool flag=false;while((!isdigit(c))&&(c!='-'))c=getchar();if(c=='-'){flag=true;c=getchar();}x=0;while(isdigit(c)){x=(x<<3)+(x<<1)+c-'0';c=getchar();}if(flag)x=-x;}void qread(unsigned&x){char c=getchar();while(!isdigit(c))c=getchar();x=0;while(isdigit(c)){x=(x<<3)+(x<<1)+c-'0';c=getchar();}}void qread(long long&x){char c=getchar();bool flag=false;while((!isdigit(c))&&(c!='-'))c=getchar();if(c=='-'){flag=true;c=getchar();}x=0;while(isdigit(c)){x=(x<<3)+(x<<1)+c-'0';c=getchar();}if(flag)x=-x;}void qread(unsigned long long&x){char c=getchar();while(!isdigit(c))c=getchar();x=0;while(isdigit(c)){x=(x<<3)+(x<<1)+c-'0';c=getchar();}}void qwrite(int x){if(x==0){putchar('0');return;}if(x<0){putchar('-');x=-x;}int stack[11];int cnt=0;while(x){stack[++cnt]=x%10;x/=10;}while(cnt)putchar(stack[cnt--]+'0');}void qwrite(unsigned x){if(x==0){putchar('0');return;}int stack[11];int cnt=0;while(x){stack[++cnt]=x%10;x/=10;}while(cnt)putchar(stack[cnt--]+'0');}void qwrite(long long x){if(x==0){putchar('0');return;}if(x<0){putchar('-');x=-x;}int stack[20];int cnt=0;while(x){stack[++cnt]=x%10;x/=10;}while(cnt)putchar(stack[cnt--]+'0');}void qwrite(unsigned long long x){if(x==0){putchar('0');return;}int stack[20];int cnt=0;while(x){stack[++cnt]=x%10;x/=10;}while(cnt)putchar(stack[cnt--]+'0');}}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	tallnut::qread(h);
	tallnut::qread(w);
	for (int i = 1;i <= h;i++)
	{
		for (int j = 1;j <= w;j++)
		{
			cc = getchar();
			switch (cc)
			{
				case '.':
					a[i][j] = true;
					break;
				case '#':
					a[i][j] = false;
					break;
				case 'S':
					a[i][j] = true;
					begx = i;
					begy = j;
					break;
				case 'T':
					a[i][j] = true;
					endx = i;
					endy = j;
					break;
			}
		}
		cc = getchar();
	}
	tallnut::qread(n);
	for (int i = 1;i <= n;i++)
	{
		tallnut::qread(r[i]);
		tallnut::qread(c[i]);
		tallnut::qread(e[i]);
		mp[r[i]][c[i]] = i;
	}
	//如果起始点没有药物:直接拉倒
	if (mp[begx][begy] == 0)
	{
		puts("No");
		return 0;
	}
	//以每个药物点为中心,向外延展,看看能到哪里
	for (int i = 1;i <= n;i++)
	{
		//广搜
		queue<point> q;
		q.push({r[i],c[i],e[i]});
		while (q.size())
		{
			tmp = q.front();
			q.pop();
			//看看是不是其他药物点
			if (mp[tmp.x][tmp.y] > 0) v[i].push_back(mp[tmp.x][tmp.y]);
			//看看是不是终点
			if (tmp.x == endx && tmp.y == endy) v[i].push_back(n + 1);
			//打标记
			visited[tmp.x][tmp.y] = true;
			//如果体力不够就拉倒
			if (tmp.energy == 0) continue;
			//向外扩展
			//上
			if (tmp.x > 1 && a[tmp.x - 1][tmp.y] && (!visited[tmp.x - 1][tmp.y]))
				q.push({tmp.x - 1,tmp.y,tmp.energy - 1});
			//下
			if (tmp.x < h && a[tmp.x + 1][tmp.y] && (!visited[tmp.x + 1][tmp.y]))
				q.push({tmp.x + 1,tmp.y,tmp.energy - 1});
			//左
			if (tmp.y > 1 && a[tmp.x][tmp.y - 1] && (!visited[tmp.x][tmp.y - 1]))
				q.push({tmp.x,tmp.y - 1,tmp.energy - 1});
			//右
			if (tmp.y < w && a[tmp.x][tmp.y + 1] && (!visited[tmp.x][tmp.y + 1]))
				q.push({tmp.x,tmp.y + 1,tmp.energy - 1});
		}
		memset(visited,0,sizeof visited);
	}
	//对着药物的图论网络开始广搜,看看能不能搜到终点
	queue<int> q;
	//起初的药物点
	q.push(mp[begx][begy]);
	while (q.size())
	{
		tmp2 = q.front();
		q.pop();
		//如果已经到终点
		if (tmp2 == n + 1)
		{
			puts("Yes");
			return 0;
		}
		//打标记
		visited2[tmp2] = 1;
		//扩展
		for (auto p : v[tmp2])
			if (!visited2[p]) q.push(p);
	}
	puts("No");
}
2024/4/6 21:52
加载中...