转载请注明出处:忆梦http://blog.youkuaiyun.com/fjy4328286/article/details/9424501
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=649
题目大意:
类似于骑士救公主的搜索题,不过是天使,而且天使有很多朋友救她(天使到底是男的还是女的丫)这里还有守卫。
每移动一步花费时间为1,而打败守卫又要花费时间1,所以要越过守卫花费的时间就是2了。
r代表天使的朋友 a代表天使 x代表守卫 #代表墙 .代表通路。
此题有个巨坑啊,在ZOJ的网站上,每一行的后面多一个空格,就最后一行没有,害得我开始还用了两个getchar(),然后就无限WA中,开始还以为我的BFS写错了,不停地看,坑了我两个小时之后,我斗胆改成了一个getchar(),就过了。
看来以后还是少用getchar,被坑了不止一次两次了啊!!!
题解:方法都是广搜
方法1.一个字符一个字符读入,读到了r就入队列,用vis数组来存储到这一坐标所需的最少的时间。 用mmin来存储到a时的最少时间。思想很朴素,经过'.'时就temp.s+1,经过'x'时就temp.s+2,然后入队列.当然如果比此坐标的vis大,也就是到达此地的时间比之前某步骤到达此地的时间长,就不如队列了,否则入队了,就相当如更新,选取了最少的时间。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<limits.h>
using namespace std;
char map[205][205];
int vis[205][205];
int n, m; //n行 m列
int mmin;
int x[] = {1,0,-1,0};
int y[] = {0,-1,0,1};
typedef struct Node
{
int x, y, s;
}Node;
queue<Node>Q;
void BFS()
{
Node temp , s;
while(!Q.empty())
{
s = Q.front();
Q.pop();
temp.x = s.x;
temp.y = s.y;
temp.s = s.s;
for(int i = 0; i < 4; i++)
{
int a = temp.x + x[i];
int b = temp.y + y[i];
if(a >= 1 && a <= n && b >= 1 && b <= m && map[a][b] != '#')
{
if(map[a][b] == 'a')
{
mmin = mmin < temp.s+1 ? mmin : temp.s+1;
continue;
}
if(map[a][b] == '.' && temp.s+1 < vis[a][b])
{
vis[a][b] = temp.s+1;
s.s = temp.s + 1;
s.x = a;
s.y = b;
Q.push(s);
}
if(map[a][b] == 'x' && temp.s+2 < vis[a][b])
{
vis[a][b] = temp.s+2;
s.s = temp.s + 2;
s.x = a;
s.y = b;
Q.push(s);
}
}
}
}
}
int main ()
{
while(scanf("%d %d", &n, &m) != EOF)
{
int i, j;
for(i = 1; i <= n; i++)
for(j = 1; j <= m; j++)
{
vis[i][j] = INT_MAX;
}
while(!Q.empty())
Q.pop();
getchar();
for(i = 1; i <= n; i++)
{
for(j = 1; j <= m; j++)
{
scanf("%c", &map[i][j]);
if(map[i][j] == 'r')
{
map[i][j] = '.';
Node temp;
temp.x = i;
temp.y = j;
temp.s = 0;
vis[i][j] = 0;
Q.push(temp);
}
}
getchar();
}
mmin = INT_MAX;
BFS();
if(mmin != INT_MAX)
printf("%d\n", mmin);
else
printf("Poor ANGEL has to stay in the prison all his life.\n");
}
return 0;
}
方法2:用优先队列,反正时间少的就排到了前面,所以一搜到a就可以直接return了,时间比前面的方法快了好多。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define N 205
int n , m;
int ans;
char map[N][N];
bool vis[N][N];
int x[] = {1,0,-1,0};
int y[] = {0,-1,0,1};
typedef struct Node
{
int x, y, t;
}Node;
priority_queue<Node>Q;
bool operator<(Node a, Node b)
{
return a.t > b.t;
}
int BFS()
{
Node temp, s;
while(!Q.empty())
{
s = Q.top();
Q.pop();
temp.x = s.x;
temp.y = s.y;
temp.t = s.t;
for(int i = 0; i < 4; i++)
{
int a = temp.x + x[i];
int b = temp.y + y[i];
if(a >= 1 && a <= n && b >= 1 && b <= m && map[a][b] != '#' && !vis[a][b])
{
if(map[a][b] == 'a')
return temp.t+1;
if(map[a][b] == '.')
{
vis[a][b] = 1;
s.t = temp.t + 1;
s.x = a;
s.y = b;
Q.push(s);
}
if(map[a][b] == 'x' )
{
vis[a][b] = 1;
s.t = temp.t + 2;
s.x = a;
s.y = b;
Q.push(s);
}
}
}
}
return -1;
}
int main ()
{
while(scanf("%d %d", &n, &m) != EOF)
{
int i, j;
while(!Q.empty())
Q.pop();
getchar();
for(i = 1; i <= n; i++)
{
for(j = 1; j <= m; j++)
{
scanf("%c", &map[i][j]);
if(map[i][j] == 'r')
{
map[i][j] = '.';
Node temp;
temp.x = i;
temp.y = j;
temp.t = 0;
vis[i][j] = 1;
Q.push(temp);
}
}
getchar();
}
memset(vis, 0, sizeof(vis));
ans = BFS();
if(ans == -1)
printf("Poor ANGEL has to stay in the prison all his life.\n");
else
printf("%d\n", ans);
}
return 0;
}