zoukankan      html  css  js  c++  java
  • hdoj 1175 (bfs)

    题意:

    判断两点之间是否可以通过至多有两次转变方向以达到相连,就是平时玩的连连看游戏,但是不能从外面绕过去。

    思路:bfs,给每个加入的队列的点添加转变方向次数turn和点当前要走的方向dir属性,起点可以走四个方向。

    参照代码来源

    我的代码,参照写得,加深练习和理解:

    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    const int M = 1005;
    int map[M][M];
    int has[M][M];
    struct node
    {
        int x,y;
        int turn;
        int dir;
    };
    int dire[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
    queue <node> q;
    int n,m;
    int sx,sy,ex,ey;
    struct node st;
    bool flag;
    inline bool in(const node &p)
    {
        if ((p.x<0 || p.y<0 || p.x>=n || p.y>=m))
            return false;
        return true;
    }
    void bfs()
    {
        node now,t;
        while (!q.empty())
        {
            now = q.front();
            q.pop();
            //cout << now.x << " " << now.y << " " << now.turn << " " << now.dir <<endl;
            if (now.x == ex && now.y == ey && now.turn<=2)  //满足条件退出
            {
                flag = true;
                return;
            }
            for (int i = 0; i < 4; i++)
            {
                if((now.dir+2)%4 == i) continue;          
                t.x=now.x+dire[i][0],t.y=now.y+dire[i][1];
                if(i == now.dir)          //now的点和下一个走的点的方向相同
                     t.turn=now.turn,t.dir=now.dir;
                else
                     t.turn=now.turn+1,t.dir=i;
                //if ((t.x>=0 && t.x < n && t.y>=0 && t.y<m) && (map[t.x][t.y] == 0|| (t.x == ex&&t.y == ey))&& (has[t.x][t.y]>=t.turn)) //如果不用in()函数的话我之前是这么写的
                if (in(t) && (map[t.x][t.y] == 0|| (t.x == ex && t.y == ey))&& (has[t.x][t.y]>=t.turn) && t.turn <= 2) // 加入队列条件
                {
                    has[t.x][t.y] = t.turn;
                    q.push(t);
                }
            }
        }
    }
    
    int main()
    {
        while (cin >> n >> m && n && m)
        {
            for (int i = 0;i < n;i++)
            {
                for (int j = 0;j < m;j++)
                    cin >> map[i][j];
            }
            int tt;
            cin >> tt;
            for (int i = 0;i < tt;i++)
            {
                cin >> sx >> sy >> ex >> ey;
                sx--,sy--,ex--,ey--;
                //printf("%d %d %d %d
    ",sx,sy,ex,ey);
                if ((sx == ex && sy == ey)|| map[sx][sy] == 0 || map[ex][ey] == 0 ||map[sx][sy] != map[ex][ey]) //判断输入的两点是否合法:是否相等,是否为0...
                {
                     puts("NO");
                     continue;
                }
                for (int i = 0;i < n;i++)
                    for (int j = 0;j < m;j++)
                        has[i][j] = 111;
                while(!q.empty())
                    q.pop();
                for (int i = 0;i < 4;i++)
                {
                    st.x = sx,st.y = sy,st.turn = 0,st.dir = i;    //起点的四个方向都要加入队列
                    q.push(st);
                }
                has[sx][sy] = 0;
                flag = false;
                bfs();
                if(flag)
                    cout << "YES
    ";
                else cout << "NO
    ";
            }
        }
        return 0;
    }
  • 相关阅读:
    P1587 [NOI2016]循环之美 杜教筛
    【学习笔记】省选动态规划类型选讲
    【模板】结构体重载高精度
    SP1716 GSS3
    SP1043 GSS1
    P1890 gcd区间 线段树
    【模板】(最小费用)最大流
    【模板】矩阵乘法
    P1073 最优贸易 DFS
    【2019.8.14】2019QB学堂DP图论班第一次考试 Problem C
  • 原文地址:https://www.cnblogs.com/ediszhao/p/4746069.html
Copyright © 2011-2022 走看看