对一个 \(n\times n\) 的棋盘,每个格子上有一个字母,表示遇到这个格子就向着某个方向走或者停止。现在给定从每个位置开始会走到的位置,或者死循环,试构造一个合法的棋盘,或者输出 INVALID。
Solution
除去死循环的部分,终点相同的点会形成独立的联通块,我们从终点开始反向 DFS 即可
如果死循环是单独的一个点,则 INVALID
否则,我们强行构造出一个二元环,然后当做第一种情况做即可
#include <bits/stdc++.h> using namespace std; const int N = 1005; char a[N][N]; int n,x[N][N],y[N][N]; void dfs1(int i,int j,int ii,int jj) { if(x[i-1][j]==ii && y[i-1][j]==jj && a[i-1][j]==0) { a[i-1][j]='D'; dfs1(i-1,j,ii,jj); } if(x[i+1][j]==ii && y[i+1][j]==jj && a[i+1][j]==0) { a[i+1][j]='U'; dfs1(i+1,j,ii,jj); } if(x[i][j-1]==ii && y[i][j-1]==jj && a[i][j-1]==0) { a[i][j-1]='R'; dfs1(i,j-1,ii,jj); } if(x[i][j+1]==ii && y[i][j+1]==jj && a[i][j+1]==0) { a[i][j+1]='L'; dfs1(i,j+1,ii,jj); } } void dfs2(int i,int j) { if(x[i-1][j]==-1 && a[i-1][j]==0) { a[i-1][j]='D'; dfs2(i-1,j); } if(x[i+1][j]==-1 && a[i+1][j]==0) { a[i+1][j]='U'; dfs2(i+1,j); } if(x[i][j-1]==-1 && a[i][j-1]==0) { a[i][j-1]='R'; dfs2(i,j-1); } if(x[i][j+1]==-1 && a[i][j+1]==0) { a[i][j+1]='L'; dfs2(i,j+1); } } signed main() { ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cin>>x[i][j]>>y[i][j]; } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==x[i][j] && j==y[i][j]) { dfs1(i,j,i,j); a[i][j]='X'; } } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(x[i][j]==-1 && a[i][j]==0) { if(x[i][j+1]!=-1&&x[i][j-1]!=-1&&x[i-1][j]!=-1&&x[i+1][j]!=-1) { cout<<"INVALID"<<endl; return 0; } else if(x[i][j+1]==-1) { dfs1(i,j+1,-1,-1); a[i][j+1]='L'; dfs1(i,j,-1,-1); a[i][j]='R'; } else if(x[i][j-1]==-1) { dfs1(i,j-1,-1,-1); a[i][j-1]='R'; dfs1(i,j,-1,-1); a[i][j]='L'; } else if(x[i-1][j]==-1) { dfs1(i-1,j,-1,-1); a[i-1][j]='D'; dfs1(i,j,-1,-1); a[i][j]='U'; } else if(x[i+1][j]==-1) { dfs1(i+1,j,-1,-1); a[i+1][j]='U'; dfs1(i,j,-1,-1); a[i][j]='D'; } } } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(a[i][j]==0) { cout<<"INVALID"<<endl; return 0; } } } cout<<"VALID"<<endl; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) cout<<a[i][j]; cout<<endl; } }
来源:https://www.cnblogs.com/mollnn/p/12460280.html