POJ 2157

题意:迷宫里面有门和钥匙,门用大写字母表示,钥匙小写。开门必须拿到迷宫中所有这个门的钥匙。给出起始点和终点,求是否能有办法走到。

 

思路:floodfill + bfs。先找能拿到哪些钥匙,判断遇到哪些门,再判断哪些门可以被打开。如果没有走到终点,就继续找钥匙。如果没有门可开了,又没有走到终点,则输出"NO"

 

易错点:这个题的细节实在多。除了代码能力要求比较高以外,要判断很多特殊情况。其中一个就是,当迷宫中有一个门,但是没有对应的钥匙。一不留神,程序就会导致门被打开了。

 

统计:244k, 0ms, 3Y

 

#include <iostream> #include <string> #define F(i,a,b) for (int i=a;i<=b;i++) using namespace std; bool mk[21][21], meetdoor[6]; int havek[6], keys[6], startx, starty, Q[402][2], move[4][2] = { {0,1}, {1,0}, {-1,0}, {0,-1} }, M, N, door[6][2]; string map[21]; bool floodfill() { int doors = 0; memset(havek, 0, sizeof(havek) ); memset(mk, 0, sizeof(mk) ); int now = 1, last = 1; Q[1][0]= startx, Q[1][1]=starty; mk[startx][starty] =true; while (now<=last) { F(i,0,3) { int newx = Q[now][0]+move[i][0], newy=Q[now][1]+move[i][1]; if (newx >=0 && newx<M && newy>=0 && newy<N) { if (mk[newx][newy] || map[newx][newy] =='X') continue; if (map[newx][newy] >=65 && map[newx][newy]<=69 ) { if (!meetdoor[ map[newx][newy] - 65 ] ) { doors++; meetdoor[ map[newx][newy] - 65 ] =true; } continue; } mk[newx][newy] = true; Q[++last][0] = newx; Q[last][1] = newy; char ch = map[newx][newy]; //key if (ch>=97 && ch<=101) havek[ch-97]++; } } now++; } F(i,0,4) { if (meetdoor[i] && havek[i] == keys[i] && keys[i] !=0 ) map[ door[i][0] ].replace( door[i][1], 1, 1, '.'); } return (doors!=0); } bool bfs() { memset(mk, 0 , sizeof(mk ) ); int now = 1, last = 1; Q[1][0] = startx, Q[1][1] = starty; mk[startx][starty] = true; while (now <= last) { F(i,0,3) { int newx = Q[now][0]+move[i][0], newy=Q[now][1]+move[i][1]; if (newx >=0 && newx<M && newy>=0 && newy<N) { char ch = map[newx][newy]; if (!mk[newx][newy] && ch !='X') { if (ch=='.' || (ch>=97 && ch<=101)) { Q[++last][0] = newx; Q[last][1] = newy; mk[newx][newy] = true; } if (ch =='G') return true; } } } now ++; } return false; } int main() { while ( cin >> M >> N && ( M!=0 && N!=0 ) ) { memset(keys, 0, sizeof(keys) ); memset(havek, 0, sizeof(havek) ); memset(meetdoor, 0, sizeof(meetdoor) ); F(i,0,M-1) { cin >> map[i]; F(j,0,N-1) { if (map[i][j] >=97 && map[i][j] <=101) keys[ map[i][j] - 97 ]++; if (map[i][j]>=65 && map[i][j]<=69) door[ map[i][j]-65 ][0] =i, door[ map[i][j] -65 ][1] = j; if (map[i][j]=='S') startx = i, starty = j; } } while (1) { bool finddoor = floodfill(); if ( bfs() ) { cout << "YES/n"; break; } if (!finddoor) { cout << "NO/n"; break; } } } return 0; }

你可能感兴趣的:(String,BI)