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;
}