HDU_1548 A strange lift
水题。bfs+优先队列。从一个位置到达还有一个位置的最少操作数。
代码清单:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct edge { int x; int t; friend bool operator<(edge a,edge b){ return a.t>b.t; } }; int N,A,B; int n[205]; int vis[205]; void bfs() { priority_queue<edge>q; edge p,w; while(q.size()) q.pop(); p.x=A; p.t=0; q.push(p); memset(vis,0x5f,sizeof(vis)); vis[A]=0; int first=1; while(q.size()) { p=q.top(); q.pop(); if(p.x==B){ first=0; printf("%d ",p.t); break; } w.x=p.x+n[p.x]; w.t=p.t+1; if(w.x>=1&&w.x<=N&&w.t<vis[w.x]) { vis[w.x]=w.t; q.push(w); } w.x=p.x-n[p.x]; if(w.x>=1&&w.x<=N&&w.t<vis[w.x]) { vis[w.x]=w.t; q.push(w); } } if(first) printf("-1 "); } int main() { while(scanf("%d",&N)!=EOF) { if(N==0) break; scanf("%d%d",&A,&B); for(int i=1;i<=N;i++) scanf("%d",&n[i]); bfs(); }return 0; }
HDU_1728 逃离迷宫
bfs。因为题目仅仅是说是否能到达,所以不须要使用优先队列。
入队时仅仅要满足转弯数小于当前转弯数就可以。
代码清单:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct edge{ int x,y; int pos,turn; }; int T,m,n; int k,x1,y1,x2,y2; char s[105][105]; int vis[105][105]; int xy[4][2]={{0,-1},{-1,0},{0,1},{1,0}}; bool bfs(){ if(x1==x2&&y1==y2) return true; queue<edge>q; while(q.size()) q.pop(); edge p,w; memset(vis,0x5f,sizeof(vis)); vis[y1][x1]=-1; for(int i=0;i<4;i++){ p.x=y1+xy[i][0]; p.y=x1+xy[i][1]; p.pos=i; p.turn=0; if(p.x>=0&&p.x<m&&p.y>=0&&p.y<n&&s[p.x][p.y]!='*') { vis[p.x][p.y]=0; q.push(p); } } while(q.size()){ p=q.front(); q.pop(); if(p.x==y2&&p.y==x2) return true; for(int i=0;i<4;i++){ w.x=p.x+xy[i][0]; w.y=p.y+xy[i][1]; w.pos=i; if(w.pos!=p.pos) w.turn=p.turn+1; else w.turn=p.turn; if(w.x>=0&&w.x<m&&w.y>=0&&w.y<n&&s[w.x][w.y]!='*'&&w.turn<=vis[w.x][w.y]&&w.turn<=k){ vis[w.x][w.y]=w.turn; q.push(w); } } } return false; } int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&m,&n); for(int i=0;i<m;i++) scanf("%s",s[i]); scanf("%d%d%d%d%d",&k,&x1,&y1,&x2,&y2); x1-=1; y1-=1; x2-=1; y2-=1; if(bfs()) printf("yes "); else printf("no "); }return 0; }
HDU_1180 诡异的楼梯
bfs+优先队列。注意的是到达楼梯时楼梯的状态可由 当前时间+当前朝向 来推断。
代码清单:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct edge { int x,y; int time; friend bool operator<(edge a,edge b){ return a.time>b.time; } }; int m,n; int sx,sy; int ex,ey; int vis[25][25]; char s[25][25]; int xy[4][2]={{0,-1},{-1,0},{0,1},{1,0}}; void bfs() { priority_queue<edge>q; while(q.size()) q.pop(); edge p,w; memset(vis,0x5f,sizeof(vis)); p.x=sx; p.y=sy; p.time=0; vis[sx][sy]=0; q.push(p); while(q.size()) { p=q.top(); q.pop(); //cout<<p.x<<" "<<p.y<<" "<<p.time<<endl; if(p.x==ex&&p.y==ey) { printf("%d ",p.time); break; } for(int i=0;i<4;i++) { w.x=p.x+xy[i][0]; w.y=p.y+xy[i][1]; if(s[w.x][w.y]=='|') { w.x+=xy[i][0]; w.y+=xy[i][1]; if(i==1 || i==3) // i 表示当前朝向 { if(p.time%2==0) w.time=p.time+1; else w.time=p.time+2; } else { if(p.time%2==0) w.time=p.time+2; else w.time=p.time+1; } } else if(s[w.x][w.y]=='-') { w.x+=xy[i][0]; w.y+=xy[i][1]; if(i==0 || i==2) { if(p.time%2==0) w.time=p.time+1; else w.time=p.time+2; } else { if(p.time%2==0) w.time=p.time+2; else w.time=p.time+1; } } else w.time=p.time+1; if(w.x>=0&&w.x<m&&w.y>=0&&w.y<n&&s[w.x][w.y]!='*'&&w.time<vis[w.x][w.y]) { vis[w.x][w.y]=w.time; q.push(w); } } } } int main() { while(scanf("%d%d",&m,&n)!=EOF) { for(int i=0;i<m;i++) { scanf("%s",s[i]); for(int j=0;j<n;j++) { if(s[i][j]=='S') { sx=i; sy=j; } if(s[i][j]=='T') { ex=i; ey=j; } } } bfs(); }return 0; }