http://acm.hdu.edu.cn/showproblem.php?pid=3309
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<math.h> 5 #include<queue> 6 using namespace std; 7 8 char s[30][30]; 9 int bx[3],by[3],hx[3],hy[3],n,m; 10 int dis[4][2]= {{1,0},{0,1},{-1,0},{0,-1}}; 11 bool vis[30][30][30][30]; 12 13 struct node 14 { 15 int x[3],y[3],f[2],step,hole[3]; 16 }; 17 queue<node > q; 18 int block(int x,int y) 19 { 20 if(x>=0&&x<n&&y>=0&&y<m&&s[x][y]!='*') 21 return 0; 22 return 1; 23 } 24 25 void init() 26 { 27 if(!q.empty()) 28 q.pop(); 29 } 30 31 int solve() 32 { 33 node temp,t2; 34 temp.x[0]=bx[0]; 35 temp.x[1]=bx[1]; 36 temp.y[0]=by[0]; 37 temp.y[1]=by[1]; 38 temp.f[0]=temp.f[1]=0; temp.hole[0]=temp.hole[1]=0; 39 temp.step=0; 40 q.push(temp); 41 vis[bx[0]][by[0]][bx[1]][by[1]]=true; 42 while(!q.empty()) 43 { 44 temp=q.front(); 45 q.pop(); 46 for(int i=0; i<4; i++) 47 { 48 int xx,yy; 49 xx=temp.x[0]+dis[i][0];//考虑第一个球 50 yy=temp.y[0]+dis[i][1]; 51 t2.f[0]=temp.f[0]; t2.hole[0]=temp.hole[0]; 52 t2.f[1]=temp.f[1]; t2.hole[1]=temp.hole[1]; 53 if(block(xx,yy)||temp.f[0]==1)// 若超这个方向遇阻了 或者球本来就在洞里 就仍留在原地 54 { 55 t2.x[0]=temp.x[0]; 56 t2.y[0]=temp.y[0]; 57 } 58 else // 否则就移一步 59 { 60 t2.x[0]=xx; 61 t2.y[0]=yy; 62 if(hx[0]==xx&&hy[0]==yy&&temp.hole[0]==0) //移一步掉 到第一个洞里 63 { 64 t2.hole[0]=1; 65 t2.f[0]=1; 66 } 67 if(hx[1]==xx&&hy[1]==yy&&temp.hole[1]==0) 68 { 69 t2.hole[1]=1; //移一步 掉到第二个洞里 70 t2.f[0]=1; 71 } 72 73 } 74 xx=temp.x[1]+dis[i][0];//考虑第二个球 75 yy=temp.y[1]+dis[i][1]; 76 if(block(xx,yy)||temp.f[1]==1||(xx==t2.x[0]&&yy==t2.y[0]))//若移一步遇阻了 或者球本来就在洞里 或 第二个求叠到到第一个球上了 77 { 78 if(xx==t2.x[0]&&yy==t2.y[0]&&t2.f[0]==0)// 若第二个压倒第一个了 切第一个不是在洞里 79 { 80 t2.x[1]=temp.x[0]; //第二个要放 第一个原来的位置上 81 t2.y[1]=temp.y[0]; 82 } 83 else 84 { 85 t2.x[1]=temp.x[1];//否则 还留在原来的位置上 86 t2.y[1]=temp.y[1]; 87 } 88 } 89 else // 其他的情况就直接走一步 90 { 91 t2.x[1]=xx; 92 t2.y[1]=yy; 93 if(hx[0]==xx&&hy[0]==yy&&temp.hole[0]==0) //调到第一个洞里 94 { 95 t2.hole[0]=1; 96 t2.f[1]=1; 97 } 98 99 if(hx[1]==xx&&hy[1]==yy&&temp.hole[1]==0) 100 { 101 t2.hole[1]=1; //调到第二个洞里 102 t2.f[1]=1; 103 } 104 } 105 t2.step=temp.step+1; 106 if(t2.hole[0]&&t2.hole[1]) 107 return t2.step; 108 if(vis[t2.x[0]][t2.y[0]][t2.x[1]][t2.y[1]]) 109 continue; 110 q.push(t2); 111 vis[t2.x[0]][t2.y[0]][t2.x[1]][t2.y[1]]=true; 112 113 } 114 } 115 return -1; 116 } 117 118 int main() 119 { 120 int i,j,t; 121 scanf("%d",&t); 122 while(t--) 123 { 124 scanf("%d%d",&n,&m); 125 //hole[0]=0; 126 //hole[1]=0; 127 int kb=0,kh=0; 128 for(i=0; i<n; i++) 129 { 130 scanf("%s",s[i]); 131 for(j=0; j<m; j++) 132 { 133 if('B'==s[i][j]) 134 { 135 bx[kb]=i; 136 by[kb++]=j; 137 } 138 if('H'==s[i][j]) 139 { 140 hx[kh]=i; 141 hy[kh++]=j; 142 } 143 } 144 } 145 int pp; 146 memset(vis,false,sizeof(vis)); 147 pp=solve(); 148 if(pp==-1) 149 printf("Sorry , sir , my poor program fails to get an answer. "); 150 else 151 printf("%d ",pp); 152 153 } 154 return 0; 155 }