(水一道题顺便看看搜索)
(以后提供C/C++两份代码)
题目描述
500年前,Jesse是我国最卓越的剑客。他英俊潇洒,而且机智过人_。
突然有一天,Jesse心爱的公主被魔王困在了一个巨大的迷宫中。Jesse听说这个消息已经是两天以后了,他知道公主在迷宫中还能坚持T天,他急忙赶到迷宫,开始到处寻找公主的下落。
时间一点一点的过去,Jesse还是无法找到公主。最后当他找到公主的时候,美丽的公主已经死了。从此Jesse郁郁寡欢,茶饭不思,一年后追随公主而去了。T_T
500年后的今天,Jesse托梦给你,希望你帮他判断一下当年他是否有机会在给定的时间内找到公主。
他会为你提供迷宫的地图以及所剩的时间T。请你判断他是否能救出心爱的公主。
输入
题目包括多组测试数据。
每组测试数据以三个整数N,M,T(0<n, m≤20, t>0)开头,分别代表迷宫的长和高,以及公主能坚持的天数。
紧接着有M行,N列字符,由".","",“P”,"S"组成。其中
“.” 代表能够行走的空地。
"" 代表墙壁,Jesse不能从此通过。
“P” 是公主所在的位置。
“S” 是Jesse的起始位置。
每个时间段里Jesse只能选择“上、下、左、右”任意一方向走一步。
输入以0 0 0结束。
输出
如果能在规定时间内救出公主输出“YES”,否则输出“NO”。
样例输入
4 4 10
…
…
…
S**P
0 0 0
样例输出
YES
典型的走迷宫求最短路径问题。
AC代码如下:
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
int next[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
char ma1p[25][25];//这里之所以不用map而是改用
int xi,yi,xt,yt;
int dp[25][25];
int N,M,T;
struct Lujin //路径的项
{
int x,y;
int t;
};
int bfs(int x,int y)
{
queue<Lujin> s;
Lujin a;
a.x = x,a.y = y,a.t = 0;
s.push(a);
Lujin b,c;
while(!s.empty())
{
b = s.front();
s.pop();//最后一个元素出队
if(b.x == xt && b.y == yt)
return b.t;
for(int i = 0;i < 4;i++)
{
c.x = b.x + next[i][0];
c.y = b.y + next[i][1];
if(c.x >= 0 && c.x <M && c.y >= 0 && c.y < N && !dp[c.x][c.y])
{
dp[c.x][c.y] = 1;
c.t = b.t +1;
s.push(c);
}
}
}
return 0;
}
int main()
{
while(cin>>N>>M>>T && N && M && T)
{
memset(dp,0,sizeof dp);
for(int i = 0;i < M;i++)
cin>>ma1p[i];
for(int i = 0;i < M;i++)
for(int j = 0;j < N;j++)
{
if(ma1p[i][j] == 'S')
{
xi = i,yi = j;
dp[i][j] = 1;
}
else if(ma1p[i][j] == 'P')
{
xt = i,yt = j;
}
else if(ma1p[i][j] == '*')
dp[i][j] = 1;
}
int t = bfs(xi,yi);
if(t > 0 && t <= T)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
不用STL的AC代码(居然因为把变量名字记混了!!!看了那么长时间都没找出错误来!!!!!!!)
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
int next_x[4] = {0,0,1,-1};
int next_y[4] = {1,-1,0,0};
char ma1p[25][25];
int xi,yi,xt,yt;
int dp[25][25];
int N,M,T;
typedef struct //路径的项
{
int x,y;
int t;
}Lujin;
Lujin s[100010];
int bfs(int x,int y)
{
int z,j;
Lujin a;
a.x = x,a.y = y,a.t = 0;
z = j = -1;
j++;
s[j] = a;
Lujin b,c;
while(z!=j)
{
b = s[z+1];//就是他!!我居然写成x+1!!!
z++;//最后一个元素出队
if(b.x == xt && b.y == yt)
return b.t;
for(int i = 0;i < 4;i++)
{
c.x = b.x + next_x[i];
c.y = b.y + next_y[i];
if(c.x >= 0 && c.x <M && c.y >= 0 && c.y < N && !dp[c.x][c.y])
{
dp[c.x][c.y] = 1;
c.t = b.t +1;
s[++j] = c;
}
}
}
return 0;
}
int main()
{
while(cin>>N>>M>>T && N&&M&&T)
{
memset(dp,0,sizeof dp);
for(int i = 0;i < M;i++)
cin>>ma1p[i];
for(int i = 0;i < M;i++)
for(int j = 0;j < N;j++)
{
if(ma1p[i][j] == 'S')
{
xi = i,yi = j;
dp[i][j] = 1;
}
else if(ma1p[i][j] == 'P')
{
xt = i,yt = j;
}
else if(ma1p[i][j] == '*')
dp[i][j] = 1;
}
int t = bfs(xi,yi);
if(t > 0 && t <= T)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
可以看出广搜中没有回溯,是一种牺牲空间来换取时间的算法。
下午出去打了会篮球有些累,今天就偷一下懒,关于深搜和广搜的详细内容就推到明天吧。