题目大意
给你一个这样的图,你可以旋转每一块,从起点到终点(玩过赛尔号的都懂)
解题思路
模拟
B
F
S
BFS
BFS,记录一下进入的方向和坐标即可
t
y
p
e
type
type 数组
从上进入是0,从左是1,从下2,从右3.这个
t
y
p
e
type
type 数组是用来计算转动角度的,比如
t
y
p
e
[
0
]
[
2
]
type[0][2]
type[0][2]意思是上一个格子从上进入,这一个格子从下进入。你会发现
4
∗
4
4*4
4∗4种情况每一种情况都和一种管子一一对应(这里面的“-1”是不合法情况),然后
t
y
p
e
[
0
]
[
1
]
type[0][1]
type[0][1] 是管子1,假如
m
a
p
[
x
]
[
y
]
map[x][y]
map[x][y]对应的是管子2,那么他们做差就是转过的角度
Code
#include <bits/stdc++.h>
#define ll long long
#define qc ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define fi first
#define se second
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define pb push_back
using namespace std;
const int MAXN = 1007;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int n, m;
// 0上 1左 2下 3右
int xx[4] = {1, 0, -1, 0};
int yy[4] = {0, 1, 0, -1};
int type[4][4] = {
{5, 1, -1, 0},
{3, 4, 0, -1},
{-1, 2, 5, 3},
{2, -1, 1, 4}
};
struct node{
int x, y, dir;
}pre[MAXN][MAXN][4];
int mp[MAXN][MAXN];
int vis[MAXN][MAXN][4];
bool check(int x, int y, int d){
if(x == n+1 && y == m && d == 0)
return 1;
if(x < 1 || x > n || y < 1 || y > m || vis[x][y][d])
return 0;
return 1;
}
void print(node nd, int st){
int x = nd.x, y = nd.y, d = nd.dir;
if(x == 1 && y == 1 && !d){
cout << st*2 << endl;
return;
}
node pr = pre[x][y][d];
print(pr, st+1);
int px = pr.x, py = pr.y, pd = pr.dir;
int tmp = type[pd][d];
if(tmp < 4){
cout << "1 " << (tmp - mp[px][py] + 4) % 4 * 90
<< " " << px << " " << py << endl;
}
else
cout << "1 " << (tmp - mp[px][py] + 2) % 2 * 90
<< " " << px << " " << py << endl;
mp[px][py] = tmp;
cout << "0 " << px << " " << py << endl;
}
int bfs(){
queue<node> q;
q.push(node{1, 1, 0});
vis[1][1][0] = 1;
while(!q.empty()){
node tmp = q.front();
q.pop();
int x = tmp.x;
int y = tmp.y;
int d = tmp.dir;
if(mp[x][y] < 4){
int nd = (d + 1) % 4;
int nx = x + xx[nd];
int ny = y + yy[nd];
if(check(nx, ny, nd)){
q.push(node{nx, ny, nd});
vis[nx][ny][nd] = 1;
pre[nx][ny][nd] = node{x, y, d};
}
nd = (d + 3) % 4;
nx = x + xx[nd];
ny = y + yy[nd];
if(check(nx, ny, nd)){
q.push(node{nx, ny, nd});
vis[nx][ny][nd] = 1;
pre[nx][ny][nd] = node{x, y, d};
}
if(nx == n+1 && ny == m && nd == 0)
return 1;
}
else{
int nd = d;
int nx = x + xx[nd];
int ny = y + yy[nd];
if(check(nx, ny, nd)){
q.push(node{nx, ny, nd});
vis[nx][ny][nd] = 1;
pre[nx][ny][nd] = node{x, y, d};
}
if(nx == n+1 && ny == m && nd == 0)
return 1;
}
}
return 0;
}
void solve(){
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
memset(vis[i][j], 0, sizeof(vis[i][j]));
cin >> mp[i][j];
}
if(bfs()){
cout << "YES\n";
print(node{n+1, m, 0}, 0);
}
else
cout << "NO\n";
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
qc;
int T;
cin >> T;
// T = 1;
while(T--){
solve();
}
return 0;
}