描述:
你是防守队员,打橄榄球时,你要绕过对方防守队员KO四分卫
6 6.Q....QQ..OO.OO..O...O.OOO.O......DD7 7.Q.....QQ.OOO....O...O......OO..OO..O..........DD0 0Q是四分卫,O是敌方防守队员,D是你,输入00结束思路:哎....一开始没审题,以为一个字母代表一个人,结果一直GG,后来才明白。这题是个广搜题。有点麻烦的地方在于D是连一块的,需要方法来让他们一起移动,一种方法是选一个中心,然后记下坐标,算出其他D的相对位置。第二种是用一个数组储存每个D。然后直接广搜就好了。代码:#include <iostream> #include <stdio.h> #include <queue> using namespace std; int dir[4][2] = {-1,0,1,0,0,-1,0,1}; int h,w,bx[21],by[21],k; char map[101][101]; int mark[101][101]; typedef struct { int bodx[21],body[21],steps; }node; node pre,cur; queue<node> q; bool judge(node a) { for(int j = 0; j < k; j++) { if(map[a.bodx[j]][a.body[j]]=='Q') return true; } return false; } node changedirec(node a,int x,int y) { for(int j = 0; j < k; j++) { a.bodx[j] = a.bodx[j] + x; a.body[j] = a.body[j] + y; } return a; } bool if_over(node a) { if(mark[a.bodx[0]][a.body[0]]==0)return false; else return true; } bool J_ifCanGo(node a) { for(int j = 0; j < k; j++) { if(a.bodx[j]<1||a.bodx[j]>h||a.body[j]<1||a.body[j]>w||map[a.bodx[j]][a.body[j]]=='O') return false; } return true; } void set_over(node a) { mark[a.bodx[0]][a.body[0]] = 1; } void bfs() { int i; pre.steps = 0; for(i = 0; i < k ; i++) { pre.bodx[i] = bx[i]; pre.body[i] = by[i]; } while(!q.empty())q.pop(); q.push(pre); set_over(pre); while(!q.empty()) { pre = q.front(); q.pop(); if(judge(pre)) { printf("%d\n",pre.steps); return; } for(i = 0; i < 4; i++) { cur = changedirec(pre,dir[i][0],dir[i][1]); cur.steps = pre.steps + 1; if(J_ifCanGo(cur)) { if(!if_over(cur)) { set_over(cur); q.push(cur); } } } } printf("Impossible\n"); } int main() { while(scanf("%d%d",&h,&w)) { if(h==0&&w==0)break; k = 0; for(int i = 1; i <= h; i++) { getchar(); for(int j = 1; j <= w; j++) { mark[i][j] = 0; scanf("%c",&map[i][j]); if(map[i][j]=='D') { bx[k] = i; by[k] = j; k++; } } } bfs(); } return 0; }