zoukankan      html  css  js  c++  java
  • POJ 2243 简单搜索 (DFS BFS A*)

    题目大意:国际象棋给你一个起点和一个终点,按骑士的走法,从起点到终点的最少移动多少次。

    求最少明显用bfs,下面给出三种搜索算法程序:

     1 // BFS
     2 #include<cstdio>
     3 #include<queue>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn=10;
     7 int r1,c1,r2,c2;
     8 struct Node
     9 {
    10     int r,c;
    11     Node(int r,int c):r(r),c(c){}
    12 };
    13 int vis[maxn][maxn];
    14 int dist[maxn][maxn];
    15 queue<Node> Q;
    16 int dr[]={-2,-2,-1,-1,1,1,2,2};
    17 int dc[]={-1,1,2,-2,2,-2,1,-1};
    18 int BFS()
    19 {
    20     if(r1==r2&&c1==c2) return 0;
    21     while(!Q.empty()) Q.pop();
    22     memset(vis,0,sizeof(vis));
    23     vis[r1][c1]=1;
    24     dist[r1][c1]=0;
    25     Q.push(Node(r1,c1));
    26     while(!Q.empty())
    27     {
    28         Node node=Q.front();Q.pop();
    29         int r=node.r,c=node.c;
    30         for(int d=0;d<8;d++)
    31         {
    32             int nr=r+dr[d];
    33             int nc=c+dc[d];
    34             if(nr>=0&&nr<8 && nc>=0 &&nc<8 &&vis[nr][nc]==0)
    35             {
    36                 if(nr==r2&&nc==c2) return dist[r][c]+1;
    37                 dist[nr][nc]=1+dist[r][c];
    38                 Q.push(Node(nr,nc));
    39                 vis[nr][nc]=1;
    40             }
    41         }
    42     }
    43     return -1;
    44 }
    45 int main()
    46 {
    47     char str1[10],str2[10];
    48     while(scanf("%s%s",str1,str2)==2)
    49     {
    50         r1=str1[1]-'1';
    51         c1=str1[0]-'a';
    52         r2=str2[1]-'1';
    53         c2=str2[0]-'a';
    54         printf("To get from %s to %s takes %d knight moves.
    ",str1,str2,BFS());
    55     }
    56     return 0;
    57 }

    DFS:

    注意visited结点,如果步数较小也继续搜索

     1 // DFS
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn=10;
     7 int r1,c1,r2,c2;
     8 struct Node
     9 {
    10     int r,c;
    11     Node(int r,int c):r(r),c(c){}
    12 };
    13 int vis[maxn][maxn];
    14 int dist[maxn][maxn];
    15 int dr[]={-2,-2,-1,-1,1,1,2,2};
    16 int dc[]={-1,1,2,-2,2,-2,1,-1};
    17 int ans;//最终答案
    18 void DFS(int r,int c,int len)
    19 {
    20     if(ans<=len || r<0 || r>=8 || c<0 || c>=8) return ;//剪枝
    21     if(r==r2&&c==c2) ans=min(ans,len);
    22     if(vis[r][c]==0 || dist[r][c]>len)
    23     {
    24         vis[r][c]=1;
    25         dist[r][c]=len;
    26     }
    27     else if(vis[r][c]==1 && len >= dist[r][c] )
    28         return ;
    29     for(int d=0;d<8;d++)
    30     {
    31         int nr=r+dr[d];
    32         int nc=c+dc[d];
    33         DFS(nr,nc,len+1);
    34     }
    35 }
    36 int main()
    37 {
    38     char str1[10],str2[10];
    39     while(scanf("%s%s",str1,str2)==2)
    40     {
    41         r1=str1[1]-'1';
    42         c1=str1[0]-'a';
    43         r2=str2[1]-'1';
    44         c2=str2[0]-'a';
    45         memset(vis,0,sizeof(vis));
    46         ans=10;
    47         DFS(r1,c1,0);
    48         printf("To get from %s to %s takes %d knight moves.
    ",str1,str2,ans);
    49     }
    50     return 0;
    51 }

    A*算法:

    g函数为沿路径从起点到当前点的移动耗费(经过的步数),启发函数h为当前格子到终点横坐标差与纵坐标差的和(曼哈顿距离),用优先队列保存每个状态按照g+h排序。通常,我们令水平或者垂直移动的耗费为10,对角线方向耗费为14。取这些值是因为沿对角线的距离是沿水平或垂直移动耗费的的根号2,或者约1.414倍。为了简化,可以用10和14近似。

    bfs

     1 #include <cstring>
     2 #include <iostream>
     3 #include <cmath>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 #include <cstdio>
     8 
     9 using namespace std;
    10 
    11 const int maxn = 10;
    12 
    13 struct Node{
    14     int x,y,step;
    15     int f,g,h;
    16     // g函数为走到当前状态的经过的步数,启发函数h为当前格子到终点横坐标差与纵坐标差的和,用优先队列保存每个状态按照g+h排序
    17     bool operator < (const Node & tmp) const{
    18         return f > tmp.f;
    19     }
    20 }node;
    21 
    22 bool visd[maxn][maxn];
    23 priority_queue<Node> Que;
    24 int dirs[8][2]={{-2,-1},{-2,1},{2,-1},{2,1},{-1,-2},{-1,2},{1,-2},{1,2}};
    25 int start_x,start_y,end_x,end_y,ans;
    26 
    27 bool isIN(int x,int y)
    28 {
    29     if(x>=8||x<0)return false;
    30     if(y>=8||y<0)return false;
    31     return true;
    32 }
    33 void init()
    34 {
    35     memset(visd,false,sizeof(visd));
    36     while(!Que.empty())Que.pop();
    37     Node S;
    38     S.x=start_x;S.y=start_y;
    39     S.step=0;S.g=0;S.h=(abs(end_x-start_x)+abs(end_y-start_y))*10;
    40     S.f=S.g+S.h;
    41     visd[S.x][S.y]=true;
    42     Que.push(S);
    43     ans=-1;
    44 }
    45 
    46 void Astar()
    47 {
    48     Node A,B;
    49     while(!Que.empty())
    50     {
    51         A=Que.top();Que.pop();
    52         if(A.x==end_x&&A.y==end_y)
    53         {
    54             ans=A.step;
    55             break;
    56         }
    57         for(int i=0;i<8;i++)
    58         {
    59             int xx=dirs[i][0]+A.x;
    60             int yy=dirs[i][1]+A.y;
    61             if(isIN(xx,yy)==false||visd[xx][yy])continue;
    62             B.x=xx;B.y=yy;
    63             B.step=A.step+1;
    64             B.g=A.g+23;
    65             B.h=(abs(end_y-yy)+abs(end_x-xx))*10;
    66             B.f=B.g+B.h;
    67             visd[B.x][B.y]=true;
    68             Que.push(B);
    69         }
    70     }
    71 }
    72 
    73 int main()
    74 {
    75     char line[10];
    76     while(gets(line))
    77     {
    78         start_x=line[0]-'a';start_y=line[1]-'1';
    79         end_x=line[3]-'a';end_y=line[4]-'1';
    80         init();
    81         Astar();
    82         printf("To get from %c%c to %c%c takes %d knight moves.
    ",line[0],line[1],line[3],line[4],ans);
    83     }
    84 
    85     return 0;
    86 }
  • 相关阅读:
    HDU 6182 A Math Problem 水题
    HDU 6186 CS Course 位运算 思维
    HDU 6188 Duizi and Shunzi 贪心 思维
    HDU 2824 The Euler function 欧拉函数
    HDU 3037 Saving Beans 多重集合的结合 lucas定理
    HDU 3923 Invoker Polya定理
    FZU 2282 Wand 组合数学 错排公式
    HDU 1452 Happy 2004 数论
    HDU 5778 abs 数论
    欧拉回路【判断连通+度数为偶】
  • 原文地址:https://www.cnblogs.com/demian/p/8310180.html
Copyright © 2011-2022 走看看