09-05 HDU_Steps4.2 BFS HDU1242 HDU1548 HDU1372 HDU1728 HDU1252 HDU2612 HDU2653 HDU2531

來源:互聯網
上載者:User

4.2.1 HDU1242 Rescue

一道簡單的BFS,有一點DP的感覺在裡面,因為打守衛會耽誤時間,所以在搜尋一個格子時不能單純的看它是否搜尋過,如果從這條路能更快的走到這個點就要對這個點進行跟新.

#include <cstdio>#include <string.h>#include <queue>using namespace std;struct pos{int x,y,step;pos(){}pos(int a,int b){x=a,y=b;}}p;char maze[205][205];int step[205][205];int ax,ay,rx,ry,n,m;int delta[2][4]={{1,-1,0,0},{0,0,1,-1}};int bfs(){queue<pos> q;while(!q.empty())q.pop();memset(step,-1,sizeof step);q.push(pos(rx,ry));step[rx][ry]=0;while(!q.empty()){pos tp=q.front();q.pop();for(int i=0;i<4;i++){int nx=tp.x+delta[0][i],ny=tp.y+delta[1][i];if(nx==ax&&ny==ay)return step[tp.x][tp.y]+1;if(maze[nx][ny]!='#'){if(step[nx][ny]==-1||step[tp.x][tp.y]+(maze[nx][ny]=='.'?1:2)<step[nx][ny]){q.push(pos(nx,ny));step[nx][ny]=step[tp.x][tp.y]+(maze[nx][ny]=='.'?1:2);} }}}return -1;}int main(){while(~scanf("%d%d",&n,&m)!=EOF){//初始化迷宮以及邊界 for(int i=1;i<=n;i++){scanf("%s",maze[i]+1);for(int j=1;j<=m;j++){if(maze[i][j]=='a')ax=i,ay=j;else if(maze[i][j]=='r')rx=i,ry=j;}}for(int i=0;i<=m+1;i++)maze[0][i]=maze[n+1][i]='#'; for(int i=0;i<=n+1;i++)maze[i][0]=maze[i][m+1]='#';int r=bfs();if(r==-1)printf("Poor ANGEL has to stay in the prison all his life.\n");else printf("%d\n",r);}return 0;}


4.2.2 HDU1548 A strange Lift

4.2.3 HDU1372 Knight Moves

兩道沒有什麼技巧的BFS..


4.2.4 HDU1728 逃離迷宮

每次跟新整行,直到不能跟新,注意:跟新的點未訪問過,或者到該點的轉向次數小於之前的決策

#include <cstdio>#include <string.h>#include <queue> using namespace std;int cas,n,m,c1,c2,r1,r2,k;char maze[205][205];int dir[205][205];struct pos{int r,c;pos(int x,int y){r=x,c=y;}};int dr[]={1,-1,0,0};int dc[]={0,0,1,-1};bool bfs(){if(r2==r1&&c2==c1)return true;queue<pos> q;memset(dir,-1,sizeof dir);q.push(pos(r1,c1));dir[r1][c1]=0;while(!q.empty()){pos tp=q.front();q.pop();for(int i=0;i<4;i++){int nr=tp.r+dr[i],nc=tp.c+dc[i];//每次跟新整行,直到不能跟新,注意(跟新的點未訪問過,或者到該點的次數小於之前的決策) while(nr>=1&&nc>=1&&nr<=m&&nc<=n&&maze[nr][nc]!='*'&&(dir[nr][nc]==-1||dir[tp.r][tp.c]+1<=dir[nr][nc])){dir[nr][nc]=dir[tp.r][tp.c]+1;q.push(pos(nr,nc));if(dir[r2][c2]!=-1&&dir[r2][c2]<=k+1)return true; nr+=dr[i];nc+=dc[i];}}}if(dir[r2][c2]<=k+1&&dir[r2][c2]!=-1)return true;return false;}int main(){scanf("%d",&cas);while(cas--){scanf("%d%d",&m,&n);for(int i=1;i<=m;i++)scanf("%s",maze[i]+1);scanf("%d%d%d%d%d",&k,&c1,&r1,&c2,&r2);printf(bfs()?"yes\n":"no\n");}return 0;} 


4.2.5 HDU1252 Hike on a Graph

題意真的是不好理解,就是說A可以到x點僅當A-x與B-C的顏色一樣

理解的題意就是一道很簡單的BFS了..用三維的VIS數組標記三個球的位置

#include <cstdio>#include <string.h>#include <queue>using namespace std;struct pos{int x,y,z;pos(int a,int b,int c){x=a,y=b,z=c;}};int n,p1,p2,p3;char map[60][60];int vis[60][60][60];/*BFS 三個點,x->i僅當color[x][i]=color[y][z] */int bfs(){memset(vis,0,sizeof vis); queue<pos> q;q.push(pos(p1,p2,p3));vis[p1][p2][p3]=1;while(!q.empty()){pos p=q.front();q.pop();if(p.x==p.y&&p.y==p.z)return vis[p.x][p.y][p.z]-1;for(int i=1;i<=n;i++){if(map[p.x][p.y]==map[p.z][i]&&!vis[p.x][p.y][i]){vis[p.x][p.y][i]=vis[p.x][p.y][p.z]+1;q.push(pos(p.x,p.y,i));}if(map[p.z][p.x]==map[p.y][i]&&!vis[p.x][i][p.z]){vis[p.x][i][p.z]=vis[p.x][p.y][p.z]+1;q.push(pos(p.x,i,p.z));}if(map[p.y][p.z]==map[p.x][i]&&!vis[i][p.y][p.z]){vis[i][p.y][p.z]=vis[p.x][p.y][p.z]+1;q.push(pos(i,p.y,p.z));}}}return -1;}int main(){while(scanf("%d",&n),n){scanf("%d%d%d",&p1,&p2,&p3);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf(" %c",&map[i][j]);int r=bfs();if(r==-1)printf("impossible\n");else printf("%d\n",r);}return 0;}

4.3.6 HDU2612 Find A Way 

找一個KFC使兩人到KFC的距離和最小,一開始從KFC考慮..TLE了

換個思路,從人來考慮,求出這兩個人到地圖上所有位置的最短距離,然後枚舉KFC位置兩人路程和就可以了..


4.3.7 HDU2653 Waiting ten thousand years for Love

這題的題意弄了很久才弄明白,對於'@'是必須要飛上去,然後在飛走的,一個'@'消耗的能量實際是兩點,而對於'.'就沒有飛與走的規定了,可以飛上走下,走上走下等等..

代碼敲的很久,可能是因為思路不清晰的緣故吧..其實每個點都去考慮兩種情況..優先去考慮飛行,因為這樣能更快的到達魔王那裡,只要能量大於0,就有可能飛行,而對於走,只要即將要走的以及出來的位置不是'@',就可以步行..另外因為到達一個點可能會有不同的能量值,所以要用一個三維的數組去標記狀態

#include <cstdio>#include <string.h>#include <queue>using namespace std;struct pos{int r,c,p,s;pos(int w,int x,int y,int z){r=w,c=x,p=y,s=z;} };int n,m,p,t,sr,sc,er,ec;bool vis[82][82][82];int dr[]={0,0,1,-1},dc[]={1,-1,0,0};char maze[82][82];int bfs(){queue<pos> q;memset(vis,0,sizeof vis);q.push(pos(sr,sc,p,0));vis[sr][sc][p]=true;while(!q.empty()){pos tp=q.front();q.pop();//reach in timeif(tp.r==er&&tp.c==ec&&tp.s<=t)return tp.sfor(int i=0;i<4;i++){int nr=tp.r+dr[i],nc=tp.c+dc[i];if(nr<1||nr>n||nc<1||nc>m||maze[nr][nc]=='#')continue;//FLY  if(tp.p>0&&!vis[nr][nc][tp.p-1]){q.push(pos(nr,nc,tp.p-1,tp.s+1));vis[nr][nc][tp.p-1]=true;}//WALKif(maze[tp.r][tp.c]=='@'||maze[nr][nc]=='@')continue;//CAN`T WALKif(!vis[nr][nc][tp.p]){q.push(pos(nr,nc,tp.p,tp.s+2));vis[nr][nc][tp.p]=true;}}}return -1; }int main(){int cas=1;while(scanf("%d%d%d%d",&n,&m,&t,&p)!=EOF){for(int i=1;i<=n;i++){scanf("%s",maze[i]+1);for(int j=1;j<=m;j++){if(maze[i][j]=='Y')sr=i,sc=j;if(maze[i][j]=='L')er=i,ec=j;}}int r=bfs();printf("Case %d:\n",cas++);if(r==-1)printf("Poor Yifenfei, he has to wait another ten thousand years.\n");else printf("Yes, Yifenfei will kill Lemon at %d sec.\n",r);}return 0;}

4.2.8 HDU2531 Catch Him

比較水,以防守隊員的左上方座標為基準座標並且用這個點來訪問標記就可以了,每次判斷的時候要對防守隊員身體的所有部分進行判定的..一開始一直WA..找了半天錯,後來發現是為了方便在一次迴圈中判定是否碰到四分衛或者捉到防守隊員了..2了一下,最後一次碰到四分衛也可能也碰到防守隊員了..這應該算沒抓到的情況..

#include <cstdio>#include <string.h>#include <queue>using namespace std;struct pos{int r,c;pos(int a,int b){r=a,c=b;}};char maze[120][120];int n,m,str,stc,fs,fsd[25][2],step[120][120];int dr[]={1,-1,0,0},dc[]={0,0,1,-1};int moveres(int nr,int nc){if(step[nr][nc]!=-1)return 0;//已移動過 for(int i=0;i<fs;i++){int r=nr-str+fsd[i][0],c=nc-stc+fsd[i][1];if(r<1||c<1||r>n||c>m)return 0;//超出邊界if(maze[r][c]=='O')return 0;//防守隊員}//注意要分開判斷,先判斷這步符不符合要求在判斷是否抓到 for(int i=0;i<fs;i++){int r=nr-str+fsd[i][0],c=nc-stc+fsd[i][1];if(maze[r][c]=='Q')return 2;//抓到四分衛 }return 1;//可以移動 }int bfs(int sr,int sc){if(sr==0)return -1;memset(step,-1,sizeof step);queue<pos> q;q.push(pos(sr,sc));step[sr][sc]=0;while(!q.empty()){pos tp=q.front();q.pop();for(int i=0;i<4;i++){int nr=tp.r+dr[i],nc=tp.c+dc[i];int r=moveres(nr,nc);//移動的結果,0不可,1可移,2抓到四分衛 if(r==2)return step[tp.r][tp.c]+1;if(r==0)continue;step[nr][nc]=step[tp.r][tp.c]+1;q.push(pos(nr,nc)); }}return -1;}int main(){while(scanf("%d%d",&n,&m),n||m){str=0,stc=0;//防守隊員左上方的座標 fs=0;//防守隊員體積 for(int i=1;i<=n;i++){scanf("%s",maze[i]+1);for(int j=1;j<=m;j++){if(maze[i][j]=='D'){fsd[fs][0]=i,fsd[fs][1]=j,fs++;if(str==0)str=i,stc=j;} }}int r=bfs(str,stc);if(r==-1)printf("Impossible\n");else printf("%d\n",r);}return 0;} 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.