Codeforces 1316 D. Nash Matrix(构造)

题目链接
题目大意:
需要构造一个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”和构造的矩阵。

解题思路:
首先考虑(x,y)=(-1,-1)的情况,这个时候只要指向周围四个点中任意一个为(-1,-1)的点就可以了,因为至少会在两个点之间来回走这也满足无法终止的条件。
然后考虑不是(-1,-1)的情况,直接从终点反过来dfs,每次dfs的下一个点就是终点与当前点相同的点,如果从终点出发走不到当前的点,就是非法的。
解题代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
char mp[maxn][maxn];
struct P{
    int x,y;
}a[maxn][maxn];
int mx[]={0,0,-1,1};
int my[]={1,-1,0,0};
char ch[]="RLUD";
char ch1[]="LRDU";
int n;
void dfs(int x,int y)
{
    for (int k=0;k<4;k++)
    {
        int dx=mx[k]+x,dy=my[k]+y;
        if (dx<1 || dx>n || dy<1 || dy>n || mp[dx][dy])
        continue;
        if (a[dx][dy].x==a[x][y].x && a[dx][dy].y==a[x][y].y)
        {
            mp[dx][dy]=ch1[k];
            dfs(dx,dy);
        }
    }
}
int main()
{
    cin>>n;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        scanf("%d%d",&a[i][j].x,&a[i][j].y);
    }
    for(int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        {
            if (a[i][j].x==-1)
            {
                for (int k=0;k<4;k++)
                {
                    int dx=i+mx[k],dy=j+my[k];
                    if (dx<1 || dx>n || dy<1 || dy>n)
                    continue;
                    if (a[dx][dy].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";
                    return 0;
                }
                //从终点反向dfs
                mp[a[i][j].x][a[i][j].y]='X';
                dfs(a[i][j].x,a[i][j].y);
            }
            //当前是(-1,-1)但是周围没有(-1,-1)  或者  从终点出发到不了
            if (!mp[i][j])
            {
                cout<<"INVALID";
                return 0;
            }
        }
    }
    cout<<"VALID\n";
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        {
            cout<<mp[i][j];
        }
        cout<<endl;
    }
}
发布了12 篇原创文章 · 获赞 1 · 访问量 327

猜你喜欢

转载自blog.csdn.net/qq_41818939/article/details/104669785