CF1316D【Nash Matrix】(dfs+构造+思维)

图论2000分

题意:需要构造一个n×n的矩阵,每个位置上有一个符号‘U’,‘D’,‘L’,‘R’,‘X’。分别表示上下左右和停止。每个坐标会有一个x,y。假设当前坐标为i,j且上面值为x,y则表示从i,j为起点会在x,y的地方终止。当(x,y)=(-1,-1)表示无法终止,当然要保证在n×n的范围内。
问是否能构造出这样的矩阵,不能就输出“INVALID”。能就输出“VALID”和构造的矩阵。

题解:学会正向思考与反向dfs相结合,这里主要运用了从终点开始反向dfs的思路,具体我们一步一步分析。我们遍历每一个点u(i,j),如果其终点是(-1,-1),那么如果合法的话它的周边必定也存在终点为(-1,-1)的点v,我们将该点u与v相连,mp[i][j]即该点u的操作方向,指向v。倘若其身边不存在这样的(-1,-1)那么直接输出INVALID终止即可。

接下来我们思考如果该点存有终点(即终点不为(-1,-1)的情况),那么其终点所代表的的mp必定为终点本身的坐标这无可置疑。所以我们先特判一下,如果不等于直接输出INVALID终止程序。否则我们从终点开始遍历,寻找其四周的边开始dfs,最后回到出发点看出发点的mp是否存在,如果不存在说明终点回不到出发点,那么说明也是INVALID的情况。

具体看代码吧,我觉得这是一道很不错的题,很考验思维

AC代码:

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e3+5;
struct node{
    int x,y;
}a[maxn][maxn];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
char mp[maxn][maxn];
char ch[]="RDLU";
char ch1[]="LURD";
int n;
void dfs(int x,int y){
    rep(k,0,3){
        int xx=x+dx[k],yy=y+dy[k];
        if(xx<1||yy<1||xx>n||yy>n||mp[xx][yy]) continue;
        if(a[x][y].x==a[xx][yy].x&&a[x][y].y==a[xx][yy].y){
            mp[xx][yy]=ch1[k];
            dfs(xx,yy);
        }
    }
}
int main(){
    scanf("%d",&n);
    rep(i,1,n){
        rep(j,1,n){
            scanf("%d%d",&a[i][j].x,&a[i][j].y);
        }
    }
    rep(i,1,n){
        rep(j,1,n){
            if(a[i][j].x==-1){
                rep(k,0,3){
                    int xx=i+dx[k],yy=j+dy[k];
                    if(xx<1||yy<1||xx>n||yy>n) continue;
                    if(a[xx][yy].x==-1){
                        mp[i][j]=ch[k];
                        break;
                    }
                }
            }
            else{
                if(mp[a[i][j].x][a[i][j].y]&&mp[a[i][j].x][a[i][j].y]!='X'){
                    cout<<"INVALID"<<endl;
                    return 0;
                }                
                mp[a[i][j].x][a[i][j].y]='X';
                dfs(a[i][j].x,a[i][j].y);
            }
            if(!mp[i][j]){
                cout<<"INVALID"<<endl;
                return 0;
            }
        }
    }
    puts("VALID");
    rep(i,1,n){
        rep(j,1,n){
            cout<<mp[i][j];
        }
        puts("");
    }
    return 0;
}
View Code

 

posted @ 2020-09-06 14:50  Anonytt  阅读(142)  评论(0编辑  收藏  举报