标签:
题目999这道题让我很焦灼啊。。。开个玩笑 哈哈
这道题的发现定义为可以直接看到对方,所以是不能走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+状态压缩)
标签:
原文地址:http://blog.csdn.net/su20145104009/article/details/50986019