标签:
被这道题坑到了,如果单纯的模拟题目所给的步骤,就会出现同一个位置要走两次的情况。。。所以对于bfs来说会很头痛。
第一个代码是wa掉的代码,经过调试才知道这个wa的有点惨,因为前面的操作有可能会阻止后面的正确操作:
#include"iostream" #include"stdio.h" #include"algorithm" #include"cmath" #include"string.h" #include"queue" #define mx 100 using namespace std; char castle[mx][mx]; int n,m,t,p,sx,sy,ex,ey; struct node { int x,y; int magic; int times; char flag;//用来标记当前位置是@还是. friend bool operator<(node a,node b) { if(b.times!=a.times) return b.times<a.times; return a.magic<b.magic; } }; int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; bool judge(int x,int y) { if(x>=0&&x<n&&y>=0&&y<m&&castle[x][y]!=‘#‘) return true; return false; } void bfs() { node cur,next; int i; cur.x=sx;cur.y=sy;cur.times=0;cur.magic=p;cur.flag=‘.‘; priority_queue<node>q; q.push(cur); while(!q.empty()) { cur=q.top(); q.pop(); // cout<<cur.x<<‘ ‘<<cur.y<<‘ ‘<<cur.magic<<‘ ‘<<cur.times<<‘ ‘<<cur.flag<<endl; if(cur.x==ex&&cur.y==ey&&cur.times<=t) { cout<<"Yes, Yifenfei will kill Lemon at "<<cur.times<<" sec."<<endl; return; } if(cur.times>t) { cout<<"Poor Yifenfei, he has to wait another ten thousand years."<<endl; return; } for(i=0;i<4;i++) { next.x=cur.x+dir[i][0]; next.y=cur.y+dir[i][1]; if(judge(next.x,next.y)) { if(cur.flag==‘@‘&&cur.magic>0) { next.times=cur.times+1; next.magic=cur.magic-1; if(castle[next.x][next.y]==‘@‘)next.flag=‘@‘; else next.flag=‘.‘; castle[next.x][next.y]=‘#‘; q.push(next); } else if(cur.flag==‘.‘) { if(castle[next.x][next.y]==‘@‘) { if(cur.magic>0) { next.times=cur.times+1; next.magic=cur.magic-1; next.flag=‘@‘; castle[next.x][next.y]=‘#‘; q.push(next); } } else { next.times=cur.times+2; next.magic=cur.magic; next.flag=‘.‘; castle[next.x][next.y]=‘#‘; q.push(next); if(cur.magic>0) { next.times=cur.times+1; next.magic=cur.magic-1; q.push(next); } } } } } } cout<<"Poor Yifenfei, he has to wait another ten thousand years."<<endl; } int main() { int c=0; while(scanf("%d%d%d%d",&n,&m,&t,&p)==4) { int i,j; for(i=0;i<n;i++) for(j=0;j<m;j++) { cin>>castle[i][j]; if(castle[i][j]==‘Y‘) {sx=i;sy=j;castle[i][j]=‘#‘;} else if(castle[i][j]==‘L‘){ex=i;ey=j;castle[i][j]=‘.‘;} } cout<<"Case "<<++c<<":"<<endl; bfs(); } return 0; }
参考大神的解法后才知道这题在一开始就应该对步骤简化,因为只有前后两步都是’.‘是才可以用走的,。其他任何情况下都要用飞的,所以没有必要像之前那样分
很多种情况讨论。果然编程之前还是要多思考思考尽量简化步骤,这样不仅可以提高效率,而且还可以避免发生不必要的错误。
#include<iostream> #include<algorithm> #include<queue> using namespace std; char g[100][100]; bool vis[88][88][88]; int n,m,p,t,si,sj,ans; int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; struct node { int step,p,x,y; node(int a=0,int b=0,int c=0,int d=0):x(a),y(b),p(c),step(d){} bool friend operator <(const node a,const node b) { return a.step>b.step; } }; void BFS() { priority_queue<node> Q; node f=node(si,sj,p,0); Q.push(f); memset(vis,false,sizeof(vis)); vis[si][sj][p]=true; node temp; while(!Q.empty()) { temp=Q.top(); Q.pop(); if(temp.step>t) return ; if(g[temp.x][temp.y]==‘L‘) { ans=temp.step; return ; } for(int k=0;k<4;k++) { int i=dir[k][0]+temp.x; int j=dir[k][1]+temp.y; if(i<0||i>n-1 || j<0 || j>m-1||g[i][j]==‘#‘) continue; if(temp.p!=0 && !vis[i][j][temp.p-1]) { vis[i][j][temp.p-1]=true; Q.push(node(i,j,temp.p-1,temp.step+1)); } if(g[temp.x][temp.y]!=‘@‘ && g[i][j]!=‘@‘&&!vis[i][j][temp.p]) { vis[i][j][temp.p]=true; Q.push(node(i,j,temp.p,temp.step+2)); } } } return ; } int main() { int cas=0; while(scanf("%d %d %d %d",&n,&m,&t,&p)==4) { for(int i=0;i<n;i++) { scanf("%s",g[i]); for(int j=0;j<m;j++) if(g[i][j]==‘Y‘) si=i,sj=j; } ans=100001; BFS(); printf("Case %d:\n",++cas); if(ans>t) printf("Poor Yifenfei, he has to wait another ten thousand years.\n"); else printf("Yes, Yifenfei will kill Lemon at %d sec.\n",ans); } return 0; }
hdu Waiting ten thousand years for Love
标签:
原文地址:http://www.cnblogs.com/acm-jing/p/4333336.html