首页 > 代码库 > nyoj999 师傅又被妖怪抓走了 (预处理+bfs+状态压缩)
nyoj999 师傅又被妖怪抓走了 (预处理+bfs+状态压缩)
题目信息
执行结果
本题排行
讨论区
师傅又被妖怪抓走了
时间限制: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
这道题让我非常焦灼啊。。。开个玩笑 哈哈
这道题的发现定义为能够直接看到对方。所以是不能走X D E 仅仅能是看到
所以在录入数据的时候 我们就提前做好预处理。
把D E的四个方向 能看到的地方都处理一下
然后就是bfs了 而在这里 我提交了几次 发现都不正确 后来无意中的一个数据启示了我
2 3 1
.S.
DXE
输出-1
2 3 3
.S.
DXE
输出3
聪明的你 看出来了吗?假设我们用通常的vis数组标记走过的路径
,对于第二条測试数据 仅仅会输出-1 由于它不会走回头路 。我又存在侥幸的心理 不用vis数组标记了 发现 果然TLE
然后就是不做了 走在路上还在想 到底在这里该怎么优化 。。。果然 睡觉的时候被我想到了 今天早上一大早 就起来做了。
详细方法是 假设又定义了两个数组visE【x】【y】 visD【x】【y】分别记录在x,y点 是否已经找到过E 或D 。
当某个点已经遍历过
我们再推断当前的visD 和visE和之前的是否一致 假设一致 我们就不用走 假设不一致 证明我们在其他点找到了D或E 如今要回来。
详细看代码把
#include <stdio.h> #include <string.h> #include <queue> #include <algorithm> using namespace std; int n,m; int t; int s1,s2; int d1,d2; int e1,e2; int dir[4][2]={1,0,0,1,-1,0,0,-1}; char map[105][105]; bool visD[105][105]; bool visE[105][105]; bool vis[105][105]; struct node { int x,y; int step; bool isfindD; bool isfindE; friend bool operator<(node a,node b) { return a.step>b.step; } }; void prepare(int x,int y,char ch) { char ch2; int x2,y2; if(ch==‘D‘) ch2=‘E‘,x2=e1,y2=e2; else ch2=‘D‘,x2=d1,y2=d2; for(int i=x-1;i>=0;i--) { if(map[i][y]==‘X‘||i==x2&&y==y2) break; if(map[i][y]==‘.‘) map[i][y]=ch; else if(map[i][y]==ch2) map[i][y]=‘*‘; else if(map[i][y]==‘S‘) { map[i][y]=ch; break; } } for(int i=x+1;i<n;i++) { if(map[i][y]==‘X‘||i==x2&&y==y2) break; if(map[i][y]==‘.‘) map[i][y]=ch; else if(map[i][y]==ch2) map[i][y]=‘*‘; else if(map[i][y]==‘S‘) { map[i][y]=ch; break; } } for(int i=y+1;i<m;i++) { if(map[x][i]==‘X‘||x==x2&&i==y2) break; if(map[x][i]==‘.‘) map[x][i]=ch; else if(map[x][i]==ch2) map[x][i]=‘*‘; else if(map[x][i]==‘S‘) { map[x][i]=ch; break; } } for(int i=y-1;i>=0;i--) { if(map[x][i]==‘X‘||x==x2&&i==y2) break; if(map[x][i]==‘.‘) map[x][i]=ch; else if(map[x][i]==ch2) map[x][i]=‘*‘; else if(map[x][i]==‘S‘) { map[x][i]=ch; break; } } } bool limit(int x,int y) { if(x==d1&&y==d2) return false; if(x==e1&&y==e2) return false; if(x<0||y<0||x>=n||y>=m||map[x][y]==‘X‘) return false; return true; } void check_result(node &temp1) { int x=temp1.x; int y=temp1.y; if(map[x][y]==‘D‘) temp1.isfindD=true; else if(map[x][y]==‘E‘) temp1.isfindE=true; else if(map[x][y]==‘*‘) temp1.isfindD=temp1.isfindE=true; } int bfs(int x1,int y1,int time) { node temp1,temp2; priority_queue<node>s; while(!s.empty()) s.pop(); temp1.x=x1;temp1.y=y1;temp1.step=0; temp1.isfindD=temp1.isfindE=false; check_result(temp1); visE[x1][y1]=temp1.isfindE; visD[x1][y1]=temp1.isfindD; vis[x1][y1]=true; s.push(temp1); while(!s.empty()) { temp1=temp2=s.top(); s.pop(); if(temp1.step>time) return -1; if(temp1.isfindD&&temp1.isfindE) return temp1.step; for(int i=0;i<4;i++) { int x1=temp1.x+dir[i][0]; int y1=temp1.y+dir[i][1]; if(limit(x1,y1)&&(!vis[x1][y1]||!(visE[x1][y1]==temp1.isfindE&&visD[x1][y1]==temp1.isfindD))) { temp1.x=x1; temp1.y=y1; temp1.step++; check_result(temp1); vis[x1][y1]=true; visE[x1][y1]=temp1.isfindE; visD[x1][y1]=temp1.isfindD; s.push(temp1); temp1=temp2; } } } return -1; } int main() { int ncase=1; while(~scanf("%d %d %d",&n,&m,&t)) { memset(map,0,sizeof(map)); for(int i=0;i<n;i++) { getchar(); for(int j=0;j<m;j++) { scanf("%c",&map[i][j]); if(map[i][j]==‘S‘) { s1=i; s2=j; } if(map[i][j]==‘D‘) { d1=i; d2=j; } if(map[i][j]==‘E‘) { e1=i; e2=j; } } } prepare(d1,d2,‘D‘); prepare(e1,e2,‘E‘); memset(visD,false,sizeof(visD)); memset(visE,false,sizeof(visE)); memset(vis,false,sizeof(vis)); printf("Case %d:\n%d\n",ncase++,bfs(s1,s2,t)); } }
nyoj999 师傅又被妖怪抓走了 (预处理+bfs+状态压缩)