zoukankan      html  css  js  c++  java
  • POJ1915Knight Moves(单向BFS + 双向BFS)

    题目链接

    单向bfs就是水题

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <queue>
     6 using namespace std;
     7 const int INF = 0x3f3f3f3f;
     8 const int Max = 300 + 5;
     9 struct Node
    10 {
    11     int x, y;
    12 };
    13 int g[Max][Max];
    14 int vis[Max][Max];
    15 int n, sx, sy, ex, ey;
    16 int gx[8] = {-1, -2, -2, -1, 1, 2, 2, 1};
    17 int gy[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    18 bool in_bound(int x, int y)
    19 {
    20     if (x >= 0 && y >= 0 && x < n && y < n)
    21         return true;
    22     return false;
    23 }
    24 int bfs(int sx, int sy)
    25 {
    26     Node node, temp;
    27     node.x = sx;
    28     node.y = sy;
    29     vis[sx][sy] = 0;
    30     queue<Node> q;
    31     q.push(node);
    32     while (!q.empty())
    33     {
    34         node = q.front();
    35         q.pop();
    36         if (node.x == ex && node.y == ey)
    37             return vis[ex][ey];
    38         for (int i = 0; i < 8; i++)
    39         {
    40             int fx = node.x + gx[i];
    41             int fy = node.y + gy[i];
    42             if (in_bound(fx, fy) && vis[fx][fy] > vis[node.x][node.y] + 1)
    43             {
    44                 temp.x = fx;
    45                 temp.y = fy;
    46                 vis[fx][fy] = vis[node.x][node.y] + 1;
    47                 q.push(temp);
    48             }
    49         }
    50     }
    51     return -1;
    52 }
    53 int main()
    54 {
    55     int test;
    56     scanf("%d", &test);
    57     while (test--)
    58     {
    59         scanf("%d", &n);
    60         scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
    61         memset(vis, INF, sizeof(vis));
    62         printf("%d
    ", bfs(sx, sy));
    63     }
    64     return 0;
    65 }
    单向bfs

    做这题主要是学着写双向bfs;

    分别从起点和终点开始搜,如果重合即找到

    从这个博客学会的

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int Max = 300 + 5;
    struct Node
    {
        int x, y;
        bool step;
    };
    // 这个step的意思之前没搞明白,他其实就是指的 在某一步下可以走到点
    //开始讲 start.step设为true,因此在只能走一次 8 个点,然后8个点都是第一步走的,然后把最后一个点的step设为true,当你走第二部时候,就是 do { 以这个点扩展 8 步} while ( !current.step) step控制了层数。 
    int g[Max][Max];
    int vis[Max][Max];
    int n, sx, sy, ex, ey;
    int gx[8] = {-1, -2, -2, -1, 1, 2, 2, 1};
    int gy[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
    bool in_bound(int x, int y)
    {
        if (x >= 0 && y >= 0 && x < n && y < n)
            return true;
        return false;
    }
    int bfs()
    {
        if (sx == ex && sy == ey)
            return 0;
        Node start, finish;
        start.x = sx;
        start.y = sy;
        start.step = true;
        finish.x = ex;
        finish.y = ey;
        finish.step = true;
        vis[sx][sy] = 1;
        vis[ex][ey] = 2;
        queue<Node> frontSearch;
        queue<Node> backSearch;
        int fstep = 0, bstep = 0;
        frontSearch.push(start);
        backSearch.push(finish);
        Node current;
        while (!frontSearch.empty() || !backSearch.empty())
        {
            if (!frontSearch.empty())
            {
                do
                {
                    current = frontSearch.front();
                    frontSearch.pop();
                    for (int i = 0; i < 8; i++)
                    {
                        int fx = current.x + gx[i];
                        int fy = current.y + gy[i];
                        if (in_bound(fx, fy))
                        {
                            if (vis[fx][fy] == 2)
                            {
                                return fstep + bstep + 1;
                            }
                            if (!vis[fx][fy])
                            {
                                vis[fx][fy] = 1;
                                Node temp;
                                temp.x = fx;
                                temp.y = fy;
                                temp.step = false;
                                frontSearch.push(temp);
                            }
                        }
                    }
                }while(current.step == false);
                fstep++;
                current = frontSearch.front();
                frontSearch.pop();
                current.step = true;  // 为了让最后队列中最后一个数step为true,先将队首拿出来,修改step,然后在入队
                frontSearch.push(current);
            }
    
            if (!backSearch.empty())
            {
                do
                {
                    current = backSearch.front();
                    backSearch.pop();
                    for (int i = 0; i < 8; i++)
                    {
                        int fx = current.x + gx[i];
                        int fy = current.y + gy[i];
                        if (in_bound(fx, fy))
                        {
                            if (vis[fx][fy] == 1)
                            {
                                return bstep + fstep + 1;
                            }
                            if (!vis[fx][fy])
                            {
                                vis[fx][fy] = 2;
                                Node temp;
                                temp.x = fx;
                                temp.y = fy;
                                temp.step = false;
                                backSearch.push(temp);
                            }
                        }
                    }
                } while(current.step == false);
                bstep++;
                current = backSearch.front();
                backSearch.pop();
                current.step = true;
                backSearch.push(current);
            }
        }
        return -1;
    }
    int main()
    {
        int test;
        scanf("%d", &test);
        while (test--)
        {
            scanf("%d", &n);
            scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
            memset(vis, 0, sizeof(vis));
            printf("%d
    ", bfs());
        }
        return 0;
    }

    第二种 双向bfs写法:

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <queue>
      6 using namespace std;
      7 const int INF = 0x3f3f3f3f;
      8 const int Max = 300 + 5;
      9 struct Node
     10 {
     11     int x, y;
     12     bool step;
     13 };
     14 int g[Max][Max];
     15 int fvis[Max][Max], bvis[Max][Max];
     16 int n, sx, sy, ex, ey;
     17 int gx[8] = {-1, -2, -2, -1, 1, 2, 2, 1};
     18 int gy[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
     19 bool in_bound(int x, int y)
     20 {
     21     if (x >= 0 && y >= 0 && x < n && y < n)
     22         return true;
     23     return false;
     24 }
     25 int bfs()
     26 {
     27     if (sx == ex && sy == ey)
     28         return 0;
     29     Node start, finish;
     30     start.x = sx;
     31     start.y = sy;
     32     start.step = true;
     33     finish.x = ex;
     34     finish.y = ey;
     35     finish.step = true;
     36     fvis[sx][sy] = 0;
     37     bvis[ex][ey] = 0;
     38     queue<Node> frontSearch;
     39     queue<Node> backSearch;
     40     int fstep = 0, bstep = 0;
     41     frontSearch.push(start);
     42     backSearch.push(finish);
     43     Node current;
     44     while (!frontSearch.empty() || !backSearch.empty())
     45     {
     46         int frontSize = (int) frontSearch.size();
     47         while (frontSize--)  // 直接将这一个队 全都 拿出来更新,就相当于上一中的step一样,控制搜索的层次
     48         {
     49             current = frontSearch.front();
     50             frontSearch.pop();
     51            
     52             for (int i = 0; i < 8; i++)
     53             {
     54                 int fx = current.x + gx[i];
     55                 int fy = current.y + gy[i];
     56                 if (in_bound(fx, fy))
     57                 {
     58                     if (bvis[fx][fy] != -1)  // 如果 倒着搜 已经搜到了,返回
     59                         return fvis[current.x][current.y] + 1 + bvis[fx][fy];
     60                     if (fvis[fx][fy] == -1) //否则正着+1
     61                     {
     62                         Node temp;
     63                         temp.x = fx;
     64                         temp.y = fy;
     65                         fvis[fx][fy] = fvis[current.x][current.y] + 1; 
     66                         frontSearch.push(temp);
     67                     }
     68                 }
     69             }
     70         }
     71         int backSize = (int) backSearch.size();
     72         while (backSize--)
     73         {
     74             current = backSearch.front();
     75             backSearch.pop();
     76            
     77             for (int i = 0; i < 8; i++)
     78             {
     79                 int fx = current.x + gx[i];
     80                 int fy = current.y + gy[i];
     81                 if (in_bound(fx, fy))
     82                 {
     83                     if (fvis[fx][fy] != -1)
     84                     {
     85                         return bvis[current.x][current.y] + 1 + fvis[fx][fy];
     86                     }
     87                     if (bvis[fx][fy] == -1)
     88                     {
     89                         Node temp;
     90                         temp.x = fx;
     91                         temp.y = fy;
     92                         bvis[fx][fy] = bvis[current.x][current.y] + 1;
     93                         backSearch.push(temp);
     94                     }
     95                 }
     96             }
     97         }
     98     }
     99     return -1;
    100 }
    101 int main()
    102 {
    103     int test;
    104     scanf("%d", &test);
    105     while (test--)
    106     {
    107         scanf("%d", &n);
    108         scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
    109         memset(fvis, -1, sizeof(fvis));
    110         memset(bvis, -1, sizeof(bvis));
    111         printf("%d
    ", bfs());
    112     }
    113     return 0;
    114 }
    双向bfs 方法二
     
  • 相关阅读:
    转帖一篇sixxpack破解的文章!
    【原创】有关Silverlight控件DataGrid的绑定数据后单元格单独复制的功能实现分析
    Worm.Win32.DownLoader.ns病毒主进程新式输入法注入分析(IME Inject)
    有关CLR的初学小整理2(可能理解不深刻,望大牛指出)
    50 years, 50 colors HDU
    匈牙利算法(求二分图最大匹配的算法)
    Can you find it? HDU
    2017广东工业大学程序设计竞赛决赛--Problem B: 占点游戏
    Proud Merchants HDU
    洗牌问题 FZU
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5342847.html
Copyright © 2011-2022 走看看