1. 程式人生 > >HDU 5025 Saving Tang Monk【bfs搜索】【北大ACM/ICPC競賽訓練】

HDU 5025 Saving Tang Monk【bfs搜索】【北大ACM/ICPC競賽訓練】

d+ push 記錄 pan bsp 難點 names 走了 lse

bfs的難點在於怎麽去表示一個問題的狀態【也就是如何去判重】

  1 #include<iostream>
  2 #include<queue>
  3 #include<cstring>
  4 #include<map>
  5 using namespace std;
  6 
  7 struct node{
  8     int r,c;
  9     int keys; 
 10     int kill;//記錄當前殺死守衛的狀態 
 11     int d;//時間
 12     bool operator < (const
node n2) const{ 13 return d>n2.d; 14 } 15 node(int r1,int c1,int k1,int k2,int d1): r(r1),c(c1),keys(k1),kill(k2),d(d1) {} 16 }; 17 18 priority_queue<node> q;//默認大根堆 19 20 char maze[105][105]; 21 int dx[4]={0,0,1,-1}; 22 int dy[4]={1,-1,0,0}; 23 bool vis[105][105][10
][32];//vis[i][j][k][l]為有沒有殺死【l所代表的守衛】拿著1-k的鑰匙到過(i,j) 24 25 int snakeID[105][105]; 26 27 int main(){ 28 //cout<<int(‘9‘)<<endl; 29 while(1){ 30 int n,m; cin>>n>>m;//m把鑰匙 31 if(n==0 && m==0) break; 32 int startr,startc,endr,endc; 33 bool
save=false; 34 35 memset(vis,0,sizeof(vis)); 36 37 int id=0; 38 for(int i=1;i<=n;i++) 39 for(int j=1;j<=n;j++){ 40 cin>>maze[i][j]; 41 if(maze[i][j]==T) { endr=i; endc=j; } 42 else if(maze[i][j]==K) { startr=i; startc=j; } 43 else if( maze[i][j]==S ) snakeID[i][j]= ++id;//在這個位置蛇的編號 44 } 45 46 //‘.‘ means a clear room as well 47 q.push( node(startr,startc,0,0,0) ); 48 vis[startr][startc][0][0]=1;//不能走了 49 50 while(!q.empty()){ 51 node n1 = q.top(); q.pop(); 52 if(n1.r==endr && n1.c==endc && n1.keys==m){ cout<<n1.d<<endl; save=true; break; } 53 54 for(int i=0;i<4;i++){ 55 int x = n1.r + dx[i]; 56 int y = n1.c + dy[i]; 57 if( x>=1 && x<=n && y>=1 && y<=n && maze[x][y]!=# ){ 58 if( maze[x][y]==S ) {//遇到蛇 59 int kill = n1.kill; 60 //看這個守衛有沒有被殺死 61 if( kill & (1<<(snakeID[x][y]-1) ) ){//守衛被殺死 62 if( !vis[x][y][n1.keys][kill] ) { 63 vis[x][y][n1.keys][kill]=1; 64 q.push( node(x,y,n1.keys,kill,n1.d+1) ); 65 } 66 } 67 else{//守衛還活著 68 if( !vis[x][y][n1.keys][kill+(1<<(snakeID[x][y]-1)) ] ){ 69 vis[x][y][n1.keys][kill+(1<<(snakeID[x][y]-1)) ]=1; 70 q.push( node(x,y,n1.keys,kill+(1<<(snakeID[x][y]-1)),n1.d+2) ); 71 } 72 } 73 } 74 else if(maze[x][y]==K || maze[x][y]==T || maze[x][y]==. ){//這三種情況一種處理方式 75 if( !vis[x][y][n1.keys][n1.kill] ){ 76 vis[x][y][n1.keys][n1.kill]=1; 77 q.push( node(x,y,n1.keys,n1.kill,n1.d+1) ); 78 } 79 } 80 else /*數字*/{ 81 //看可不可以拿 82 int key = int(maze[x][y])-48; 83 if( n1.keys>=key || n1.keys!=key-1 ){//拿過了或拿不了 84 if( !vis[x][y][n1.keys][n1.kill] ){ 85 vis[x][y][n1.keys][n1.kill]=1; 86 q.push( node(x,y,n1.keys,n1.kill,n1.d+1) ); 87 } 88 } 89 else{//可以拿 90 if( !vis[x][y][key][n1.kill] ){ 91 vis[x][y][key][n1.kill]=1; 92 q.push( node(x,y,key,n1.kill,n1.d+1) ); 93 } 94 } 95 } 96 } 97 } 98 } 99 if(!save) cout<<"impossible"<<endl; 100 while(!q.empty()) q.pop(); 101 } 102 103 return 0; 104 }

記得用priority_queue的時候如果往裏面放node,自己重載小於號的形式是在struct裏寫:

【記得要寫const】

bool operator < (const node n2) const{
  // return  .....
}

HDU 5025 Saving Tang Monk【bfs搜索】【北大ACM/ICPC競賽訓練】