hdu 2531 Catch him
http://acm.hdu.edu.cn/showproblem.php?pid=2531
大意:防守队员只能平移,且一次移动一步,问碰到进攻球员的最少移动步数,每个队员的身体有多个格子构成,防守队员最多不超过20格,广搜!
1 //变形广搜 2 #include <stdio.h> 3 #include <iostream> 4 #include <queue> 5 #include <string.h> 6 using namespace std; 7 char map[105][105]; 8 bool vis[105][105]; 9 int dir[8][2]={{1,0},{-1,0},{0,1},{0,-1}}; 10 int h,w; 11 int t; 12 typedef struct { 13 int bodx[21],body[21],step; 14 }node; 15 node pre,now; 16 queue<node>q; 17 void set_over(node a)//标记路过的点 18 { 19 vis[a.bodx[0]][a.body[0]]=1; 20 } 21 bool can_go(node a)//判断能否走过 22 { 23 for(int i=0;i<t;i++) 24 { 25 if(a.bodx[i]<1||a.bodx[i]>h||a.body[i]<1||a.body[i]>w||map[a.bodx[i]][a.body[i]]=='O') 26 return 0; 27 } 28 return 1; 29 } 30 bool is_over(node a)//判断是否走过 31 { 32 if(vis[a.bodx[0]][a.body[0]]) 33 return 1; 34 return 0; 35 } 36 node change(node a,int x,int y)//移动 37 { 38 for(int i=0;i<t;i++) 39 { 40 a.bodx[i]+=x; 41 a.body[i]+=y; 42 43 } 44 a.step+=1; 45 return a; 46 } 47 bool judge(node a)//判断是否擒杀 48 { 49 for(int i=0;i<t;i++) 50 { 51 if(map[a.bodx[i]][a.body[i]]=='Q') 52 return 1; 53 } 54 return 0; 55 } 56 void bfs()//广搜 57 { 58 memset(vis,0,sizeof(vis)); 59 while(!q.empty()) 60 q.pop(); 61 q.push(pre); 62 set_over(pre); 63 while(!q.empty()) 64 { 65 pre=q.front(); 66 q.pop(); 67 if(judge(pre)) 68 { 69 printf("%d\n",pre.step); 70 return; 71 } 72 for(int i=0;i<4;i++) 73 { 74 now=change(pre,dir[i][0],dir[i][1]); 75 if(can_go(now)) 76 { 77 if(!is_over(now)) 78 { 79 q.push(now); 80 set_over(now); 81 } 82 } 83 } 84 } 85 printf("Impossible\n"); 86 } 87 int main() 88 { 89 while(cin>>h>>w) 90 { 91 t=0; 92 if(h==0&&w==0) 93 break; 94 for(int i=1;i<=h;i++) 95 for(int j=1;j<=w;j++) 96 { 97 cin>>map[i][j]; 98 if(map[i][j]=='D') 99 { 100 pre.bodx[t]=i; 101 pre.body[t++]=j; 102 } 103 } 104 pre.step=0; 105 bfs(); 106 } 107 return 0; 108 }