poj2243 -- Knight Moves

题目意思:骑士游历的问题咯,单向广搜能过,也可以拿来练习双向广搜咯,附双向广搜代码

View Code
  1 #include <iostream>
  2 #include <queue>
  3 #include <cstdio>
  4 using namespace std;
  5 #define MAX 10
  6 struct Status   // 结构
  7 {
  8     int x,y;    //位置
  9     int vis;
 10 };
 11 int visited[MAX][MAX];//标记数组
 12 int dir[8][2]={{-2, -1}, {-2, 1}, {-1, -2}, {-1, 2}, {1, -2}, {1, 2}, {2, -1}, {2, 1}};
 13 int n,m;// n * m 矩形
 14 int ans[MAX][MAX];//标记前面走了多少步
 15 
 16 int result;//结果走的步数
 17 queue<Status> Q1;  // 正向队列
 18 queue<Status> Q2;  // 反向队列
 19 bool found; //标记成功找到
 20 Status s1,s2;//s1开始位置  s1结束位置
 21 
 22 void BFS_expand(queue<Status> &Q,bool flag)
 23 {  
 24     Status s,t;
 25     s=Q.front();  // 从队列中得到头结点s
 26     Q.pop();
 27     for(int i=0;i<8;i++)
 28     {
 29         t.x=s.x+dir[i][0];
 30         t.y=s.y+dir[i][1];    
 31         t.vis = s.vis + 1;
 32         if(t.x>=1 && t.x<=n && t.y>=1 && t.y<=m )  // 判是否越界            
 33         {
 34             if(flag)   // 在正向队列中判断
 35             {
 36                 if (visited[t.x][t.y]!=1) // 没在正向队列出现过
 37                 {
 38                     if(visited[t.x][t.y]==2)  // 该状态在反向队列中出现过
 39                     {    
 40                         found=true;
 41                         result = ans[t.x][t.y] + ans[s.x][s.y];
 42                         return;
 43                     }
 44                     ans[t.x][t.y] = t.vis;    
 45                     visited[t.x][t.y]=1;   // 标记为在在正向队列中
 46                     Q.push(t);  // 入队
 47                 }
 48             }
 49             else    // 在反向队列中判断
 50             {
 51                 if (visited[t.x][t.y]!=2) // 没在反向队列出现过
 52                 {
 53                     if(visited[t.x][t.y]==1)  // 该状态在正向向队列中出现过
 54                     {            
 55                         found=true;
 56                         result = ans[t.x][t.y] + ans[s.x][s.y];
 57                         return;
 58                     }
 59                     ans[t.x][t.y] = t.vis;    
 60                     visited[t.x][t.y]=2;  // 标记为在反向队列中
 61                     Q.push(t);  // 入队
 62                 }
 63             }
 64         }
 65     } 
 66 }
 67 
 68 void TBFS()
 69 {
 70     memset(visited,0,sizeof(visited));  // 判重数组
 71     while(!Q1.empty())  Q1.pop();   // 正向队列
 72     while(!Q2.empty())  Q2.pop();  // 反向队列
 73     //======正向扩展的状态标记为1,反向扩展标记为2
 74     visited[s1.x][s1.y]=1;   // 初始状态标记为1
 75     visited[s2.x][s2.y]=2;   // 结束状态标记为2
 76 
 77     s1.vis = 0;
 78     s2.vis = 1;
 79 
 80     ans[s1.x][s1.y] = 0;
 81     ans[s2.x][s2.y] = 1;
 82 
 83     Q1.push(s1);  // 初始状态入正向队列
 84     Q2.push(s2);  // 结束状态入反向队列
 85     while(!Q1.empty() || !Q2.empty())
 86     {
 87         if(!Q1.empty())
 88             BFS_expand(Q1,true);  // 在正向队列中搜索
 89         if(found)  // 搜索结束 
 90             return ;
 91         if(!Q2.empty())
 92             BFS_expand(Q2,false);  // 在反向队列中搜索
 93         if(found) // 搜索结束
 94             return ;
 95     }
 96 }
 97 
 98 
 99 int main(void)
100 {
101     n=8;
102     m=8;
103     char anss[2][4];
104     while(scanf("%s %s",anss[0],anss[1])!=EOF)
105     {
106         found = false;
107         if(strcmp(anss[0],anss[1])==0)
108         {
109             printf("To get from %s to %s takes 0 knight moves.\n",anss[0],anss[1]);
110         }
111         else
112         {
113             s1.x = anss[0][0]-'a'+1;
114             s1.y = anss[0][1] - '0';
115             s2.x = anss[1][0]-'a'+1;
116             s2.y = anss[1][1] - '0';
117             result = 0;
118             TBFS();
119             printf("To get from %s to %s takes %d knight moves.\n",anss[0],anss[1],result);
120         }
121     }
122     return 0;
123 }
posted @ 2012-08-18 17:13  Wheat″  阅读(152)  评论(0)    收藏  举报