POJ 2312

坦克大戰,童年回憶

這道題比較特殊的在於磚牆的出力,很明白的就可以想到距離變爲2,然而這樣在使用BFS尋求最短路徑的時候違背了一個原則,算法導論上有這部分詳細介紹,就是關於每時每刻隊列內是一個單調不減的數列,此外,頭和尾插值最大爲1,一次推入一個距離爲2的,會破壞BFS這些性質,所以想了一個這種的方法,即,不侷限於二維,每次遇到磚塊,先“跳到”高一維度,距離僅增加一,而同時在高一維度,只能跳回二維世界,這樣強制增加一個額外經過的點,便可以解決這個問題

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
using namespace std;

const int maxw= 305;

char mz[maxw][maxw];
int vis[maxw][maxw], dis[maxw][maxw], bw[maxw][maxw];
int step[4][2]= {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int si, sj;

int BFS(int m, int n)
{
	memset(vis, 0, sizeof(vis));
	memset(bw, 0, sizeof(bw));
	vis[si][sj]= 1;
	dis[si][sj]= 0;
	queue<pair<int, int> > Q;
	Q.push(make_pair(si, sj));
	int x, y, nx, ny;
	int v;

	while (!Q.empty()){
		x= Q.front().first;
		y= Q.front().second;
		Q.pop();
		v= dis[x][y]+1;
		if (bw[x][y]){
			dis[x][y]= v;
			bw[x][y]= 0;
			Q.push(make_pair(x, y));
			continue;
		}

		for (int i= 0; i< 4; ++i){
			nx= x+step[i][0];
			ny= y+step[i][1];
			if ('T'== mz[nx][ny]){
				return v;
			}
			if (nx> 0 && nx<= m && ny> 0 && ny<= n && !vis[nx][ny]){
				if ('E'== mz[nx][ny]){
					vis[nx][ny]= 1;
					dis[nx][ny]= v;
					Q.push(make_pair(nx, ny));
				}
				else if ('B'== mz[nx][ny]){
					bw[nx][ny]= 1;
					vis[nx][ny]= 1;
					dis[nx][ny]= v;
					Q.push(make_pair(nx, ny));
				}
			}
		}
	}

	return -1;
}

int main()
{
	int m, n;
	while (~scanf("%d %d", &m, &n) && m){
		for (int i= 1; i<= m; ++i){
			scanf("%s", mz[i]+1);
			for (int j= 1; j<= n; ++j){
				if ('Y'== mz[i][j]){
					si= i;
					sj= j;
				}
			}
		}
		printf("%d\n", BFS(m, n));
	}

	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章