您的位置:首页 > 其它

nyoj999

2016-01-09 21:28 148 查看

师傅又被妖怪抓走了

时间限制:1000 ms  |  内存限制:65535 KB

难度:3

描述
话说唐僧复得了孙行者,师徒们一心同体,共诣西方。自宝象国救了公主,承君臣送出城西,沿路饥餐渴饮,悟空便为师傅去化斋,等悟空回来,悟净慌慌张张的对悟空说:“不好了,不好了”,还没等悟净说完,悟空说:“师傅又被妖怪抓走了”,悟净:“NO!” ,悟空一脸茫然,悟净:“师傅和二师兄都被妖怪抓走了”。悟空(晕!)。为了防止悟空救人,妖怪先把唐憎和八戒分别藏起来,如果悟空在T分钟之后还没找到人,那必定是被妖怪吃掉了。假设悟空在一个n行m列的矩阵内,悟空在每一分钟可以走到上,下,左,右的其中的一个可以走的位置,每次只能走一步。我们把发现定义为可以直接看到对方,也就是说两个人在同一行或者同一列,并且中间没有障碍物或者没有其他人就可以看到对方。

输入有多组测试数据,每组首先是三个正整数n , m (3<=n,m<=100), T,(0<=T<=100) 分别代表行数,列数,规定的时间。接下来n 行,每行 m 个字符。其中’ S ’ 代表悟空的位置,’ D ’代表师傅位置,’ E ’代表八戒的位置。并且保证都只有一个. ’ X ’代表墙 ,’ . ’代表空地 .输出每组先输出一行Case c:(c表示当前的组数,从1开始计数);

接下来一行,如果悟空可以在规定时间内找到两人,则输出最少需要的时间,否则输出-1。样例输入
5 6 3
XXD...
....E.
....X.
....S.
......
5 6 3
XDX...
....E.
......
....S.
......
5 6 8
XXDX..
.XEX..
......
....S.
......

样例输出
Case 1:
-1
Case 2:
3
Case 3:
-1

题目很简单,就是广搜,而且我没有经过优化就水过了,,看了数据很水,,可以提前对地图进行优化:

比如可以看到师傅的点标记为1,

看到八戒的点标记为2,

同时看到两个的标记为3,

否则为0,用另外一个二维flag存,这样每次队首弹出判断的时候就不用上下左右遍历,直接访问flag[][],判断,

注意题目还是有一些坑的,就是你走过的点可能还要走,例子:

2 6 10

EXXXXD

 . . S . . .

答案为7而不是1,所以用isv[x][y][f1][f2]四维数组做标记,代码如下;

还有!!!注意行n,长m,是矩形不是方形!!!

代码如下:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int n,m,T;
int inf=1<<29;
bool isv[105][105][2][2];//注意访问过的点与是否找到人的状态还有关
int map[105][105];
int xx[4][2]={0,-1, 0,1, -1,0, 1,0};
struct node{
int i,j;
int t;
bool f1,f2;
node(){
}
node(int x,int y,int tt,bool f11,bool f22){
i=x;j=y;t=tt;f1=f11;f2=f22;
}
};

//没到一个点就上下左右判断可以提前对地图预处理加快速度
void find(int x,int y,node &t){
for (int i=x+1;i<=n&&map[i][y]!=0;i++){
if (map[i][y]==2){
t.f1=1;break;
}
else if (map[i][y]==3){
t.f2=1;break;
}
}
for (int i=x-1;i>=1&&map[i][y]!=0;i--){
if (map[i][y]==2){
t.f1=1;break;
}
else if (map[i][y]==3){
t.f2=1;break;
}
}
for (int i=y-1;i>=1&&map[x][i]!=0;i--){
if (map[x][i]==2){
t.f1=1;break;
}
else if (map[x][i]==3){
t.f2=1;break;
}
}
for (int i=y+1;i<=m&&map[x][i]!=0;i++){
if (map[x][i]==2){
t.f1=1;break;
}
else if (map[x][i]==3){
t.f2=1;break;
}
}
return;
}
int main(){
char c;
node t;
bool f1t,f2t;
int x,y,t1,t2,ans,num=1;
while(cin>>n>>m>>T){
ans=-1;
memset(map,0,sizeof(map));
memset(isv,0,sizeof(isv));
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
cin>>c;
if (c=='.') map[i][j]=1;
else if (c=='D') map[i][j]=2;
else if (c=='E') map[i][j]=3;
else if (c=='S') {
map[i][j]=1;
x=i;y=j;
}
}
}
queue<node> q;
isv[x][y][0][0]=1;
q.push(node(x,y,0,0,0));
while(!q.empty()){
t=q.front();
find(t.i,t.j,t);
if (t.f1&&t.f2){
ans=t.t;
break;
}
q.pop();
for (int i=0;i<4;i++){
t1=t.i+xx[i][0];
t2=t.j+xx[i][1];
if (!isv[t1][t2][t.f1][t.f2]&&(map[t1][t2]==1)){
if (t.t+1<=T){
isv[t1][t2][t.f1][t.f2]=1;
q.push(node(t1,t2,t.t+1,t.f1,t.f2));
}
}
}
}
cout<<"Case "<<num++<<":"<<endl;
cout<<ans<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BFS图的搜索