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;
    }
  • 相关阅读:
    PAT A1094 The Largest Generation (25 分)——树的bfs遍历
    PAT A1055 The World's Richest (25 分)——排序
    PAT A1052 Linked List Sorting (25 分)——链表,排序
    PAT A1076 Forwards on Weibo (30 分)——图的bfs
    辅导员
    辅导员面试
    C程序设计
    Excel VBA 基本概念
    Excel函数
    导入excel表的数据到数据库ssh
  • 原文地址:https://www.cnblogs.com/czsharecode/p/9606425.html
Copyright © 2011-2022 走看看