Traffic Light(bfs)2019省赛训练-5

25 篇文章 0 订阅
21 篇文章 0 订阅
这篇博客讨论了如何解决一个关于城市交通灯路径的最短时间问题。城市由n×m个交叉路口组成,每个交叉口有一个交通灯,状态为0或1,规定了车辆的移动方向。博主提出使用BFS(广度优先搜索)算法,并通过异或操作处理交通灯状态的变化,来寻找从起点到终点的最短时间。如果无法到达终点,则输出-1。
摘要由CSDN通过智能技术生成

题目

Description

DreamGrid City is a city with n×mn×m intersections arranged into a grid of nn rows and mm columns. The intersection on the ii-th row and the jj-th column can be described as (i,j)(i,j), and two intersections (i1,j1)(i1,j1) and (i2,j2)(i2,j2) are connected by a road if |i1−i2|+|j1−j2|=1|i1−i2|+|j1−j2|=1.

At each intersection stands a traffic light. A traffic light can only be in one of the two states: 0 and 1. If the traffic light at the intersection (i,j)(i,j) is in state 0, one can only move from (i,j)(i,j) to (i+1,j)(i+1,j) or (i−1,j)(i−1,j); If the traffic light is in state 1, one can only move from (i,j)(i,j)to (i,j+1)(i,j+1) or (i,j−1)(i,j−1) (of course, the destination must be another intersection in the city).

BaoBao lives at the intersection (si,sj)(si,sj), and he wants to visit his best friend DreamGrid living at the intersection (fi,fj)(fi,fj). After his departure, in each minute the following things will happen in order:

  • BaoBao moves from his current intersection to another neighboring intersection along a road. As a law-abiding citizen, BaoBao has to obey the traffic light rules when moving.
  • Every traffic light changes its state. If a traffic light is in state 0, it will switch to state 1; If a traffic light is in state 1, it will switch to state 0.

As an energetic young man, BaoBao doesn't want to wait for the traffic lights, and he must move in each minute until he arrives at DreamGrid's house. Please tell BaoBao the shortest possible time he can move from (si,sj)(si,sj) to (fi,fj)(fi,fj) to meet his friend, or tell him that this is impossible.

Input

There are multiple test cases. The first line of the input contains an integer TT, indicating the number of test cases. For each test case:

The first line contains two integers nn and mm (1≤n×m≤1051≤n×m≤105), indicating the size of the city.

For the following nn lines, the ii-th line contains mm integers ti,1,ti,2,…,ti,mti,1,ti,2,…,ti,m (0≤ti,j≤10≤ti,j≤1), where ti,jti,j indicates the initial state of the traffic light at intersection (i,j)(i,j).

The next line contains four integers sisi, sjsj, fifi and fjfj (1≤si,fi≤n1≤si,fi≤n, 1≤sj,fj≤m1≤sj,fj≤m), indicating the starting intersection and the destination intersection.

It's guaranteed that the sum of n×mn×m over all test cases will not exceed 3×1053×105.

Output

For each test case output one line containing one integer, indicating the shortest possible time (in minute) BaoBao can move from (si,sj)(si,sj)to (fi,fj)(fi,fj) without stopping. If it is impossible for BaoBao to arrive at DreamGrid's house, print "-1" (without quotes) instead.

Sample Input

4
2 3
1 1 0
0 1 0
1 3 2 1
2 3
1 0 0
1 1 0
1 3 1 2
2 2
1 0
1 0
1 1 2 2
1 2
0 1
1 1 1 1
Sample Output

3
5
-1
0

题意:t组样例,n,m,下面是n行m列的数组,由01组成,0代表只能往上下走,1只能往左右走,每走一步要变换(0变成1,1变成0),给出起点位置和终点位置,问最少几步能从起点到终点,不能到达输出-1.

思路:1.因为最短的路,用bfs。

           2.因为数据量范围n*m<=1e5,肯定开不了[1e5][1e5]的数组,所以用vector存

          3.怎么处理01转换问题呢,用异或,.time里面存的是现在的步数,用现在的位置跟。time%2异或就是现在该位置的值。

          4.注意清零。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <deque>
#include <vector>
#define MAX 0x3f3f3f3f
#define fori(a,b) for(int i=a;i<=b;i++)
#define forj(a,b) for(int j=a;j<=b;j++)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const double PI = acos(-1);
const int M=1e5+10;
struct node
{
    ll x;
    ll y;
    ll time;
} now,start;
ll n,m,ex,ey,sx,sy;
vector <ll> vv[M],vis[M];
queue <node> dq;
void init()
{
    ll i,j;
    for(i=0; i<n; i++)
    {
        vv[i].clear();
        vis[i].clear();
        for(j=0; j<m; j++)
            vis[i].push_back(0);
    }
    while(!dq.empty())
        dq.pop();
}
ll bfs()
{
    ll i,j;
    start.x=sx;
    start.y=sy;
    start.time=0;
    vis[sx][sy]=1;
    dq.push(start);
    while(!dq.empty())
    {
        now=dq.front();
        dq.pop();
        if(now.x==ex&&now.y==ey)
            return now.time;
        ll f;
        f=vv[now.x][now.y]^(now.time%2);
        if(f==0)//只能往上下走
        {
            ll dir[2][2]= {-1,0,1,0};
            for(i=0; i<2; i++)
            {
                start.x=now.x+dir[i][0];
                start.y=now.y+dir[i][1];
                start.time=now.time+1;
                if(start.x>=0&&start.x<n&&start.y>=0&&start.y<m&&vis[start.x][start.y]==0)
                {
                    vis[start.x][start.y]=1;
                    dq.push(start);
                }
            }
        }
        else//只能往左右走
        {
            ll dir[2][2]= {0,1,0,-1};
            for(i=0; i<2; i++)
            {
                start.x=now.x+dir[i][0];
                start.y=now.y+dir[i][1];
                start.time=now.time+1;
                if(start.x>=0&&start.x<n&&start.y>=0&&start.y<m&&vis[start.x][start.y]==0)
                {
                    vis[start.x][start.y]=1;
                    dq.push(start);
                }
            }
        }

    }
    return-1;
}
int main()
{
    ll i,j,t;
    cin>>t;
    while(t--)
    {

        cin>>n>>m;
        init();
        for(i=0; i<n; i++)
            for(j=0; j<m; j++)
            {
                ll f;
                cin>>f;
                vv[i].push_back(f);
            }
        cin>>sx>>sy>>ex>>ey;
        sx-=1;//因为给的坐标是从1开始的,所以要想转换成0起点的,要减一
        sy-=1;
        ex-=1;
        ey-=1;
        ll ans=bfs();
        cout<<ans<<endl;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值