NYOJ 82
法一:
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef struct pos
{
int x,y;
} POS;
int d[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int bfs(POS from);
char maze[20][20];
int key[5];
queue<pos> que;
int row,col;
POS start;
int main()
{
int i,j;
while(scanf("%d%d",&row,&col) && (row + col))
{
for(i = 0 ; i < 5 ; ++i)
key[i] = 0;
for(i = 0 ; i < row ; ++i)
{
scanf("%s",maze[i]);
for(j = 0 ; j < col ; ++j)
{
if(maze[i][j] == 'S')//记录起点
{
start.x = i; start.y = j;
}
if(maze[i][j]>= 'a' && maze[i][j]<= 'e')//统计各个门所需的钥匙数量
++key[maze[i][j]-'a'];
}
}//for(i)
que.push(start);
if(bfs(start)) puts("YES");
else puts("NO");
while(!que.empty()) que.pop();
}
// system("pause");
return 0;
}
int bfs(POS from)
{
POS p,next;
int i,t;
maze[from.x][from.y] = 'X';
while(!que.empty())
{
p = que.front();
que.pop();
for(i = 0 ; i < 4 ; ++i)
{
next.x = p.x + d[i][0];
next.y = p.y + d[i][1];
if(next.x>=0 && next.x < row && next.y>=0 && next.y < col)
{
if(maze[next.x][next.y] == 'G')//找到终点,结束
return true;
if(maze[next.x][next.y] == '.')//可以走 进队列
{
que.push(next);
maze[next.x][next.y] = 'X';
}
else
{
if(maze[next.x][next.y]>='a' && maze[next.x][next.y] <= 'e')
{
que.push(next);
--key[maze[next.x][next.y]-'a'];//记录找到的钥匙数量
maze[next.x][next.y] = '.';
}
else
if(maze[next.x][next.y]>='A' && maze[next.x][next.y] <= 'E')
{
t = maze[next.x][next.y] - 'A';
/*
这个地方相当关键啊!
*/
if(!key[t])//用钥匙把门打开即可
{
que.push(next);
// maze[next.x][next.y] = 'X';
}
else//钥匙不够,就把原来的p进队列,先走其他的路,以寻找其他的钥匙
{
if(!que.empty()) que.push(p);
}
}
}
}//if
}//for()
}//while()
return 0;
}
法二:
#include <queue>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
using namespace std;
typedef struct
{
int x,y;
}Ac;
queue <Ac> S,door[5];
int dir[]={0,1,0,-1,1,0,-1,0};
int from_x,from_y,to_x,to_y;
int lock[5],key[5];
int map[25][25];
bool in[25][25];
bool bfs()
{
while(!S.empty())
{
Ac R = S.front();
S.pop();
if(R.x == to_x && R.y == to_y)
return true;
for(int k=0;k<8;)
{
int x = R.x + dir[k++];
int y = R.y + dir[k++];
if(!in[x][y] && map[x][y]) //路或钥匙
{
S.push({x,y});
in[x][y]=1;
if(map[x][y]>0) //钥匙
{
key[map[x][y]-1]++;
map[x][y]=-1;
}
}
}
if(S.empty())
{
memset(in,0,sizeof(in));
int find=0;
for(int i=0;i<5;i++)
{
if(key[i] && key[i]==lock[i])//芝麻开门
{
key[i]=0,find=1;
while(!door[i].empty())
{
R = door[i].front();
int x = R.x;
int y = R.y;
map[x][y]=-1;
door[i].pop();
}
}
}
if(find)
S.push({from_x,from_y});
else
break;
}
}
return false;
}
void clear()
{
while(!S.empty())
S.pop();
for(int i=0;i<5;i++)
while(!door[i].empty())
door[i].pop();
}
int main()
{
int h,w;
while(scanf("%d%d",&h,&w),h||w)
{
getchar();
memset(lock,0,sizeof(lock));
memset(map,0,sizeof(map));
memset(key,0,sizeof(key));
memset(in,0,sizeof(in));
for(int i=1;i<=h;i++)
{
for(int j=1;j<=w;j++)
{
char c = getchar();
switch(c)
{
case 'S':from_x=i;from_y=j;S.push({i,j});break;
case 'G':to_x=i,to_y=j;
case '.':map[i][j]=-1;break;
}
if(islower(c)) //钥匙
{
lock[c-'a']++;
map[i][j] = c-'a'+1;
}
if(isupper(c) && c!='G' && c!='S' && c!='X')//门
{
door[c-'A'].push({i,j});
}
}
getchar();
}
bool yes=bfs();
if(yes)
puts("YES");
else
puts("NO");
clear();
}
return 0;
}