• BFS: 刷题专用


    BFS 刷题


    看了一天的图方面的东西,这个东西,真的是,思路都懂,但是实现起来,哈哈哈哈哈哈哈,一直处于懵逼的状态,所以就找点题刷吧,加强理解与应用,突然有点理解高中的应试教育了。

    POJ 3984

    题目描述

    它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
    题目链接:http://poj.org/problem?id=3984

    这个题,其实就是一个基本的BFS搜索,找最短路线,对于BFS。从出发点开始,第一次遍历到终点时过的那条路径就是最短的路径。因为这条路径没有多绕一个不相关节点啊,所以它是最短的。但是这个题并不是简单的去求这条路有多长,他得求出路径,所以需要存储遍历时候的路径的顺序。

    #include <stdio.h>
    #include <stdbool.h>
    
    struct Node{
        int x, y;
        int pre;
        int level;
    };
    int pos[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}; //右,左,上,下
    int main() {
        int i, j;
        int num[5][5] = {0};
        struct Node queue[30]; //建立队列
        struct Node result[30];
        int rear = 0;
        int head = 0;
        int visit[5][5] = {0};
        struct Node root;
        int cnt = 0;
        bool flag = false;
       // printf("你好");
        for (i = 0; i < 5; i++)
            for (j = 0; j < 5; j++) {
                scanf("%d", &num[i][j]);
            }
        queue[rear].x = 0; //第一个元素入队
        queue[rear].y = 0;
        queue[rear].level = 0;
        queue[rear].pre = -1;
        result[cnt++] = queue[rear];
        rear += 1;
        visit[0][0] = 1;
        int parent;
        while(rear != head){ //队不为空;
            root = queue[head++]; //出队;
            i = -1;
            parent = root.level; //获取层次
            if(root.x == 4 && root.y == 4){
                flag = true;
                break;
            }
            while (i < 3){//四个方向
                i += 1;
                int x = root.x + pos[i][0];
                int y = root.y + pos[i][1];
                if(x < 0 || y< 0 || y > 4 || x > 4 || visit[x][y] == 1 || num[x][y] == 1)
                    continue;
                //printf("%d ", rear);
                queue[rear].x = x;
                queue[rear].y = y;
                queue[rear].pre = parent;
                queue[rear].level = cnt; //他的层次;
                result[cnt++] = queue[rear];
                visit[x][y] = 1;
                rear += 1;
            }
        }
        cnt = parent;
        i = 0;
        while(cnt != -1){
            queue[i++] = result[cnt];
            cnt = result[cnt].pre;
        }
        for(i = i - 1; i > 0; i--)
         printf("(%d, %d)
    ",queue[i].x,queue[i].y);
         printf("(4, 4)");
    
    }
    

    POJ 1979

    题目描述

    There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles.

    Write a program to count the number of black tiles which he can reach by repeating the moves described above.

    就只是简简单单的遍历图的过程,记录最多可以遍历多少个点
    题目链接http://poj.org/problem?id=1979

    #include<stdio.h>
    #include<stdlib.h>
    #include <stdbool.h>
    
    struct Node
    {
        int x;
        int y;
        int pre;
    };
    int pos[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}; //上下左右四个方向
    int main()
    {
        int m,n;
        char arr[1000][1000];
        while(true)
        {
            scanf("%d %d",&m,&n);
            if(m == 0 && n == 0)
                return 0;
            int i = 0;
            int j = 0;
            int begin_x;
            int begin_y;
            bool visit[1000][1000] = {false}; //用来标志还没被访问;
            struct Node queue[1000]; //用队列来存储节点;
            int rear = 0;
            int head = 0;
            int cnt = 0;
            getchar();
            for(i = 0; i < n; i++)
            {
                for(j = 0; j < m; j++)
                {
                    scanf("%c",&arr[i][j]);
                    if(arr[i][j] == '@')
                    {
                        begin_x = i;
                        begin_y = j;
                    }
                }
                        getchar();
    
            }
            queue[rear].x = begin_x;
            queue[rear].y = begin_y;
            rear += 1;
            cnt += 1;
            visit[begin_x][begin_y] = true;
            while(head != rear){
                struct Node root = queue[head++];
                for(i = 0; i < 4; i++){
                    int x = root.x + pos[i][0];
                    int y = root.y + pos[i][1];
                    if(x < 0 || y < 0 || x >= n || y >= m || visit[x][y] || arr[x][y] == '#')
                        continue;
                    cnt += 1;
                    queue[rear].x = x;
                    queue[rear].y = y;
                    rear += 1;
                    visit[x][y] = true;
                }
            }
            printf("%d
    ",cnt);
        }
        return 0;
    }
    
    
  • 相关阅读:
    Linux下修改Mysql最大并发连接数
    linux ORACLE备份还原(EXPIMP)
    免安装Oracle客户端使用PL/SQL连接Oracle
    连接ORACLE客户端工具navicat111.12 for oracle
    安装Oracle 11.2.0.3 Client Win 32-bit
    sharepoint 2013创建网站集,域帐户无法访问,只有administrator可以访问
    VS2013 ERROR SCRIPT5009: “WebForm_AutoFocus”未定义
    TimeUnit类 java.util.concurrent.TimeUnit
    Redis: 分布式锁的正确实现方式(转)
    java synchronized实现可见性对比volatile
  • 原文地址:https://www.cnblogs.com/xmxj0707/p/9678309.html
Copyright © 2020-2023  润新知