zoukankan      html  css  js  c++  java
  • 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 '
    '
    #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
    Codeforces ID:Anonytt QQ: 847399102 可以添加&关注
  • 相关阅读:
    [poj3974] Palindrome 解题报告 (hashmanacher)
    SQL Android
    SharedPreferences Android
    本地广播 localBroadcastManager Android
    RecyclerView Android
    自定义ListView Android
    布局 Android
    传值 Android
    活动的生命周期 Android
    CodeForces 907F Power Tower(扩展欧拉定理)
  • 原文地址:https://www.cnblogs.com/Anonytt/p/13621725.html
Copyright © 2011-2022 走看看