http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1649
//hnldyhy(303882171) 11:12:46 // zoj 1649 //bfs +优先队列 #include <stdio.h> #include <iostream> #include <queue> using namespace std; struct node { int x; int y; int step; }; bool operator<(const node &a,const node &b) { if (a.step>b.step) return true; else return false; } char g[201][201]; int main() { int m,n,i,j; node start,end,temp,t,tx; priority_queue <node>q,x; //x队列用于暂存由x变成的r,在下一回合再push进q bool c; int s[4][2]={{0,1}, {0,-1}, {1,0}, {-1,0}}; while (scanf("%d%d",&m,&n)!=EOF) { c=false; for (i=0;i<m;i++) { scanf("%s",g[i]); for (j=0;j<n;j++) { if (g[i][j]=='r') { start.x=j; //起始点进q start.y=i; start.step=0; q.push(start); } if (g[i][j]=='a') { end.x=j; //记录结束点 end.y=i; } } } while (!q.empty()||!x.empty()) { while (!x.empty()) //将x里的元素push进q里 { tx=x.top(); x.pop(); q.push(tx); } temp=q.top(); q.pop(); for (i=0;i<4;i++) //上下左右进行扩张 { t=temp; t.x=t.x+s[i][0]; t.y=t.y+s[i][1]; if (t.x<0||t.x>=n||t.y<0||t.y>=m) continue; if (g[t.y][t.x]=='.') { g[t.y][t.x]='r'; t.step=t.step+1; q.push(t); } if (g[t.y][t.x]=='x') { g[t.y][t.x]='r'; //勿忘标记, t.step=t.step+2; x.push(t); } if (g[t.y][t.x]=='a') { c=true; break; } } if (c) break; } if (c) printf("%d ",temp.step+1); else printf("Poor ANGEL has to stay in the prison all his life. "); while (!q.empty()) q.pop(); //一定要清,否则超内存 } return 0; } zoj 1649 // bfs搜索:x的出现是难点。每次过x的时候step是要+2 #include <iostream> #include <cstdio> #include <string> #include <string.h> #include <queue> #include <iomanip> using namespace std; string map[210]; int flag[210][210]; struct node { int x; int y; int step; }; int way[4][2]={0,1,0,-1,1,0,-1,0}; bool operator<(const node &a,const node &b) { if(a.step>b.step) return true; else return false; } int main() { int i,j,n,m,cur; node t,tt; bool fail; priority_queue <node>q; while( cin>>n>>m ) { memset( flag,0,sizeof(flag) ); for( i=0;i<n;i++ ) cin>>map[i]; for( i=0;i<n;i++ ) { for( j=0;j<m;j++ ) { if( map[i][j]=='r' ) { t.x=i; t.y=j; t.step=1; flag[t.x][t.y]=1; q.push(t); } } } fail=true; cur=1; while( !q.empty() ) { t=q.top(); q.pop(); if( map[t.x][t.y]=='a' ) { fail=false; cout<<t.step-1<<endl; break; } for( i=0;i<4;i++ ) { tt.x=t.x+way[i][0]; tt.y=t.y+way[i][1]; if( tt.x>=0 && tt.x<n && tt.y>=0 && tt.y<m && !flag[tt.x][tt.y] ) { if( map[tt.x][tt.y]=='.' || map[tt.x][tt.y]=='a' ) { // cout<<tt.x<<" "<<tt.y<<" "<<t.step+1<<endl; tt.step=t.step+1; flag[tt.x][tt.y]=tt.step; q.push( tt ); } else if( map[tt.x][tt.y]=='x' ) { tt.step=t.step+2; //每次过x的时候step是要+2 flag[tt.x][tt.y]=tt.step; q.push( tt ); } } } } if( fail ) cout<<"Poor ANGEL has to stay in the prison all his life. "; while( !q.empty() ) q.pop(); } return 0; }
// hnldyhy(303882171) 10:26:24 // zoj 1649 #include<iostream> #include<stdio.h> #include <string.h> #include<queue> #define MAXMN 200 #define INF 1000000 //走到每个位置所需时间的初始值无穷大 using namespace std; struct point//表示到达某个方格时的状态 { int x,y;//方格的位置 int time;//走到当前位置所花时间 }; queue<point> Q;//队列中的结点为当前angel的朋友所处的位置 int N,M;//监狱的大小 char map[MAXMN][MAXMN];//地图 int mintime[MAXMN][MAXMN];//走到每个位置所需最少时间 int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//4个相邻方向:上,右,下,左 int ax,ay;//angle所在的位置 int BFS(point s) { int i; point hd,t; Q.push(s); while (!Q.empty())//当队列非空 { hd=Q.front(); Q.pop(); for (i=0;i<4;i++) { int x=hd.x+dir[i][0],y=hd.y+dir[i][1]; if (x>=0&&x<=N-1&&y>=0&&y<=M-1&&map[x][y]!='#') //排除边界 和 墙壁 { t.x=x; t.y=y; t.time=hd.time+1; if (map[x][y]=='x') t.time++;//杀死警卫队多花一个单位时间 if (t.time<mintime[x][y])//如果这种走法比之前走到(x,y)位置所花的时间更少,则把t入队列 //否则t无需入队列 { mintime[x][y]=t.time; Q.push(t);//t入队 } } } } return mintime[ax][ay]; } int main() { int i,j,sx,sy; point start; while (scanf("%d%d",&N,&M)!=EOF) { memset(map,0,sizeof(map)); for (i=0;i<N;i++) scanf("%s",map[i]);//读入地图 for (i=0;i<N;i++) for (j=0;j<M;j++) { mintime[i][j]=INF; if (map[i][j]=='a') { ax=i; ay=j; } else if (map[i][j]=='r') { sx=i; sy=j; } } start.x=sx; start.y=sy; start.time=0; mintime[sx][sy]=0; int mint=BFS(start);//返回到达angle位置的最少时间,有可能为INF if (mint<INF) cout<<mint<<endl; else cout<<"Poor ANGEL has to stay in the prison all his life. "; } return 0; }