生化武器2【搜索】

In the warm-up, Gogo has used the mysterious “Pidun Shu”, and he found it very powerful. So he decides to perform it to his good friend SJ alone. Gogo performs it in a small room. He disappears suddenly and left the “chemical weapon”, which diffuses to up, down, left and right. And SJ also escapes to the four directions. Within one second, the gas moves first, then, SJ moves. Each time they move one grid. SJ does not want to be poisoned. So he ask you to calculate that SJ can reach the all safe places after t seconds(Of course in the middle, you can not be “poison” too).

当气体不能扩散的时候,人就觉得安全了,他就不会动了。但,当人不能动的时候,气体一样会扩散。

数据保证有且只有一个’G’和一个’S’。


这道题搜索不难,有一个大坑需要注意/(ㄒoㄒ)/~~WA在这好几次

  1. 一旦气体无法扩散,人也就不会走了,可以直接break。如何判断气体无法扩散呢?只要一次扩散过程中气体的格数不再增加即可。

然后我们按照,G可以覆盖S和。, S只能覆盖。的原则来进行扩散,直到所有时间都用光了或者全场没有任何S可以行动。

string a[MAX];
ll gx, gy, sx, sy, M, N, T, t;
ll dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };

int main() {
	cin >> T;
	while (T--) {
		cin >> M >> N >> t;
		for (int i = 1; i <= M; i++) {
			cin >> a[i];
			for (int j = 0; j < N; j++) {
				if (a[i][j] == 'G')gx = i, gy = j;
				else if (a[i][j] == 'S')sx = i, sy = j;
			}
		}
		//q1存储poison扩散的地方,q2存储用户可以跑到的地方
		queue<P> q1, q2; q1.push(P(gx, gy));
		vector<P> v1, v2; q2.push(P(sx, sy));
		ll cnt = 1;//记录S的个数
		//q1.size()>0,气体不能扩散的时候,人就不会动了
		for (int i = 1; i <= t && cnt > 0 && q1.size() > 0; i++) {
			v1.clear(); v2.clear(); cnt = 0; ll sign = 0;//标记气体是否扩散了
			while (!q1.empty()) {
				ll tx = q1.front().first, ty = q1.front().second; q1.pop();
				for (int j = 0; j < 4; j++) {
					ll x = tx + dx[j], y = ty + dy[j];
					if (x<1 || x>M || y < 0 || y >= N || a[x][y] == 'X' || a[x][y] == 'G')
						continue;//已经是病毒或者是墙
					if (a[x][y] == '.' || a[x][y] == 'S') {//可以扩散
						a[x][y] = 'G'; v1.push_back(P(x, y)); sign = 1;
					}
				}
			}
			if (!sign)break;//气体不扩散,人就不动了
			for (unsigned i = 0; i < v1.size(); i++)q1.push(v1[i]);
			while (!q2.empty()) {
				ll tx = q2.front().first, ty = q2.front().second; q2.pop();
				if (a[tx][ty] == 'G')continue;//这个地方已经被侵染了
				for (int j = 0; j < 4; j++) {
					ll x = tx + dx[j], y = ty + dy[j];
					if (x<1 || x>M || y < 0 || y >= N || a[x][y] == 'X' || a[x][y] == 'S' || a[x][y] == 'G')
						continue;
					a[x][y] = 'S'; v2.push_back(P(x, y));
				}
			}
			for (unsigned j = 0; j < v2.size(); j++)q2.push(v2[j]);
			for (int j = 1; j <= M; j++)
				for (int k = 0; k < N; k++)
					if (a[j][k] == 'S')cnt++;
		}
		cnt = 0;
		for (int j = 1; j <= M; j++)
			for (int k = 0; k < N; k++)
				if (a[j][k] == 'S')cnt++;
		if (cnt > 0) 
			for (int i = 1; i <= M; i++)
				cout << a[i] << endl;
		else cout << "No" << endl;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值