题意:

给定n*m 大小矩阵, 出发点所在列, 终点所在列 (行统一在第一行和最后一行)

下面 2*i - 1 行给出 矩阵中墙壁存在与否

 

问沿着右边墙壁走,从起点走到终点 ,再从终点走到起点能否遍历所有方格

思路:

BFS模拟题意,队列存边

 

#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<set>
#include <cstdio>  
#include <cstring>  
#include <iostream>  
#include <math.h>  
#include <queue>  
#define N 1500
#define ll double  
using namespace std;  
inline ll Min(ll a,ll b){return a>b?b:a;}
inline ll Max(ll a,ll b){return a>b?a:b;}

int map[N][N];
int n, m, enter, out;
struct node{
	int x,y,from;
	node(int a=0,int b=0,int c=0):x(a),y(b),from(c){}
};
int go(int x){// turn right
	if(x==1)return 4;
	if(x==2)return 1;
	if(x==3)return 2;
	if(x==4)return 3;
}
int go2(int x){// turn left
	if(x==1)return 2;
	if(x==2)return 3;
	if(x==3)return 4;
	if(x==4)return 1;
}
bool Inmap(int x,int y){
	if(x<0 || y<0 || x>=(n<<1) || y>=(m<<1))return false;
	return true;
}
bool hehe(node a){//could turn right
	if(a.from==1)
	{ 
		a.from = 4;
		if( Inmap(a.x,a.y+2) && !map[a.x][a.y+1])
			return true;
		return false;
	}
	if(a.from==2)
	{ 
		a.from = 1;
		if( Inmap(a.x-2,a.y) && !map[a.x-1][a.y])
			return true;
		return false;
	}
	if(a.from==3)
	{ 
		a.from = 2;
		if( Inmap(a.x,a.y-2) && !map[a.x][a.y-1])
			return true;
		return false;
	}
	if(a.from==4)
	{ 
		a.from = 3;
		if( Inmap(a.x+2,a.y) && !map[a.x+1][a.y])
			return true;
		return false;
	}
}
node zz(node a){//after turn right,the coordinate
	if(a.from==1)
	{ 
		a.from = 4;
		if( Inmap(a.x,a.y+2) && !map[a.x][a.y+1])
			a.y+=2;;
		return a;
	}
	if(a.from==2)
	{ 
		a.from = 1;
		if( Inmap(a.x-2,a.y) && !map[a.x-1][a.y])
			a.x-=2;
		return a;
	}
	if(a.from==3)
	{ 
		a.from = 2;
		if( Inmap(a.x,a.y-2) && !map[a.x][a.y-1])
			a.y-=2;
		return a;
	}
	if(a.from==4)
	{ 
		a.from = 3;
		if( Inmap(a.x+2,a.y) && !map[a.x+1][a.y])
			a.x+=2;
		return a;
	}
}
int vis[N][N],papa[N][N]; //papa是记录是否访问过该点   vis是BFS后这个访问的点

void BFS(node hehehe, node endd){ // hehehe为起点 endd为终点
	memset(vis,0,sizeof(vis));
	queue<node>q;
	q.push(hehehe);
	while(!q.empty()){
		node E = q.front(); q.pop();
		vis[E.x][E.y] ++;
		if(E.x == endd.x && E.y == endd.y && E.from == endd.from)return; //注意走到终点后方向也必须是确定的

		if(hehe(E))
		{
			node now = zz(E);
			if(vis[now.x][now.y]<=2){q.push(now);continue;}
		}
		E.from = go2(E.from);
		if(hehe(E))
		{
			node now = zz(E);
			if(vis[now.x][now.y]<=2){q.push(now);continue;}
		}
		E.from = go2(E.from);
		if(hehe(E))
		{
			node now = zz(E);
			if(vis[now.x][now.y]<=2){q.push(now);continue;}
		}
		E.from = go2(E.from);
		if(hehe(E))
		{
			node now = zz(E);
			if(vis[now.x][now.y]<=2){q.push(now);continue;}
		}
	}
}

int main(){
	int T, i, j, temp;scanf("%d",&T);
	while(T--){
		memset(map,0,sizeof(map));
		scanf("%d %d %d %d",&n,&m,&enter,&out);
		enter++, out++;
		for(i = 1; i< (2*n); i++)
		{
			if(i&1)
			{
				temp = m-1;
				for(j = 1; temp-- ;j+=2)
					scanf("%d",&map[i][j]);
			}
			else 
			{
				temp = m;
				for(j = 0; temp--; j+=2)
				{
					scanf("%d",&map[i][j]);
					if(temp)
						map[i][j+1]=1;
				}
			}
		}
		memset(papa,0,sizeof(papa));
		BFS(node(1,(enter-1)<<1,3), node(1+((n-1)<<1),(out-1)<<1,4));

		for(i = 1; i < (n<<1); i+=2)for(j = 0; j < (m<<1); j+=2)if(vis[i][j]>0)	papa[i][j]=1;

		BFS( node(1+((n-1)<<1),(out-1)<<1,1), node(1,(enter-1)<<1,2));

		for(i = 1; i < (n<<1); i+=2)	for(j = 0; j < (m<<1); j+=2)if(vis[i][j]>0)
					papa[i][j]=1;

		bool ok = true;
		for(i = 1; i < (n<<1) && ok; i+=2)
			for(j = 0; j < (m<<1) && ok; j+=2)
				if(!papa[i][j])		ok = false;
		if(ok)
			printf("YES\n");
		else 
			printf("NO\n");
	}
	return 0;
}
/*
99

3 4 1 2
0 0 0
1 1 0 1
0 0 0
0 0 0 0
1 0 0

2 2 1 2
0
1 0
0

2 2 1 2
0
1 0
0

2 2 1 2
0
0 1
0

3 3 2 2
0 0
0 1 0
1 1
0 1 0
0 0

3 3 2 2
0 0
0 0 0
0 0
0 0 0
0 0

4 3 1 3
0 0
0 0 0
0 0 
0 0 0
0 0
0 0 0
0 0

4 3 1 2
0 0
0 1 0
1 1
0 0 0
1 1 
0 0 0
1 0

4 3 1 2
0 0
0 1 0
1 0
0 0 1
1 0
0 0 0
1 0


ans:
y
y
y
y
n
n
n

y
y
*/