zoukankan      html  css  js  c++  java
  • ZOJ

    【传送门】http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4020

    【题目大意】从起点(sx, sy)出发,要到达(ex , ey)。每次从点(x,y)走的时候要看红绿灯,灯的状态为1时只能左右走,走到(x , y+1)或者 (x , y-1);灯为0的时候只能上下走,走到(x +1, y)或者 (x-1 , y)。现在问能不能从源点走到终点,如果能,输出最少需要走多少步。

      注意(x,y)代表第x行第y列,不是传统意义上的坐标系。

    【题解】求最短路一般用BFS,但是与一般的图不同,这里灯的状态是不断变化的,所以允许走的方向也不同。不妨记一个步数t, t % 2 == 1或者0时方向不同,需要入队的点也不同。

      另外有这样一个事实,只要访问过的点,或者说之前已经入过队的点以后都不会再入队,证明如下:

      若过之前经过一个点(x0, y0), 经过若干步骤以后,又回到了(x0, y0),那么经过了多少步呢?把沿途所有点相连,必然构成一个长方形或者一条来回的直线,很显然,他们的周长必然是2的倍数,也就是偶数,因此再到这一点时这个灯的状态和上一次经过时是一样的,所以没有任何意义。当然也可能发生了这样一个情况:主人公会在这个矩形中循环走动或者在这条线段来回走动,均无法到达终点。

    【代码】

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <vector>
    using namespace std;
    
    struct Node
    {
        //点的坐标  走过的步数 
        int x, y, step;
    };
    
    int dic1[4] = { 1,-1,0,0 };
    int dic2[4] = { 0,0,-1,1 };
    
    vector<vector<int> >maps;
    vector<vector<bool> >vis;
    
    int sx, sy, ex, ey;
    int state;
    int n, m;
    
    //判断点是否能够入队 
    bool judge(int x, int y)
    {
        if (x > 0 && x <= n && y> 0 && y <= m && vis[x][y] == 0)
        {
            return true;
        }
        return false;
    }
    
    //BFS求最短路 
    int bfs(Node s)
    {
        queue <Node> Q;
        Q.push(s);
        Node p, q;
        vis[s.x][s.y] = true;
        
        while (!Q.empty())
        {
            p = Q.front();
            Q.pop();
            //如果已经到达终点就直接返回步数即可 
            if (p.x == ex && p.y == ey)
            {
                return p.step;
            }
            state = maps[p.x][p.y];
            //看看走到这一点共走了多少步,奇数步需要反转灯的状态,偶数步相当于不用反转 
            if ((p.step) % 2 == 1)
            {
                if (state == 1)
                {
                    state = 0;
                }
                else
                {
                    state = 1;
                }
            }
            //看这一点的状态(0,1) 确定能走到那两个点,将能到达的点入队 
            if (state == 0)
            {
                for (int i = 0; i<2; i++)
                {
                    q.x = p.x + dic1[i];
                    q.y = p.y + dic2[i];
    
                    if (judge(q.x, q.y) == true)
                    {
                        vis[q.x][q.y] = true;
                        q.step = p.step+1;
                        Q.push(q);
                    }
                }
            }
            else if (state == 1)
            {
                for (int i = 2; i<4; i++)
                {
                    q.x = p.x + dic1[i];
                    q.y = p.y + dic2[i];
    
                    if (judge(q.x, q.y) == true)
                    {
                        vis[q.x][q.y] = true;
                        q.step = p.step + 1;
                        Q.push(q);
                    }
                }
            }
        }
        return -1;
    }
    int main()
    {
        ios::sync_with_stdio(false); 
        int cas;
        cin >> cas;
        while (cas--)
        {
            cin >> n >> m;
            maps.clear();
            vis.clear();
            maps.resize(n + 1);
            vis.resize(n + 1);
            for (int i = 1; i <= n; i++)
            {
                maps[i].resize(m + 1);
                vis[i].resize(m + 1);
            }
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    cin >> maps[i][j];
                }
            }
            cin >> sx >> sy >> ex >> ey;
            if (sx == ex && sy == ey)
            {
                cout << 0 << endl;
                continue;
            }
            Node t;
            t.x = sx;
            t.y = sy;
            t.step = 0;
            state = maps[sx][sy];
    
            int ans = bfs(t);
            cout << ans << endl;
        }
        return 0;
    }
  • 相关阅读:
    Linux磁盘分区实例演示
    浅谈Linux下的rpm
    You have 1 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): shopadmin. Run 'python manage.py migrate' to apply them.
    Xshell Linux常用命令
    OSError: mysql_config not found
    AttributeError: module 'datetime' has no attribute 'now'
    CentOS查看进程端口号以及kill操作
    nginx报错 nginx: [alert] kill(25903, 1) failed (3: No such process)
    3D 散点图的绘制
    关系数据库和非关系型数据
  • 原文地址:https://www.cnblogs.com/czsharecode/p/9606425.html
Copyright © 2011-2022 走看看