【Codeforces】CodeCraft-20 (Div. 2) D - Nash Matrix

110 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

题目链接

Problem - 1316D - Codeforces

题目

image.png

题目大意

一个游戏里有 nnnn 列的地图,地图的每个格子上都有一个字符,格子 (x,y)(x,y) 中可能出现的字符及其含义如下:

  • ‘X’:到达格子 (x,y)(x,y) 后游戏结束。
  • ‘U’:到达格子 (x,y)(x,y) 后应该向上走,去 (x1,y)(x-1,y)
  • ‘D’:到达格子 (x,y)(x,y) 后应该向下走,去 (x+1,y)(x+1,y)
  • ‘L’:到达格子 (x,y)(x,y) 后应该向左走,去 (x,y1)(x,y-1)
  • ‘R’:到达格子 (x,y)(x,y) 后应该向右走,去 (x,y+1)(x,y+1)

给出以每个格子为起点出发将在哪个格子游戏结束,如果从该格子出发游戏永远不停止将会给出 (1,1)(-1,-1),试判断输入是否描述了一张合法的游戏地图。如果合法,输出任何满足描述的游戏地图。

思路

首先我们考虑哪些信息是已知可以填到地图上的——如果一个格子的坐标和它的结束游戏位置相同,那么该格子的值一定是 ‘X’;如果有两个相邻的格子以他们为起点将永远不会结束游戏,那么它们可以直接被设置为环路。

向所有已经填入信息的格子 (i,j)(i,j) 的上下左右方向扩展,如果与其相邻的格子 (x,y)(x,y)(i,j)(i,j) 结束游戏格子相同,就让 (x,y)(x,y) 的下一步走向 (i,j)(i,j),即填上 (x,y)(x,y) 的答案。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1002;
int dtx[4]={0,0,1,-1};
int dty[4]={1,-1,0,0};
char val[4]={'L','R','U','D'};
char dvl[4]={'R','L','D','U'};

int n;
char ans[N][N];
struct asdf{
	int x,y;
}nw;

int a[N][N][2],h,t;
asdf d[N*N];
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;++i)
		for (int j=1;j<=n;++j)
		{
			ans[i][j]=0;
			scanf("%d%d",&a[i][j][0],&a[i][j][1]);
			if (a[i][j][0]==i&&a[i][j][1]==j)
			{
				d[++t]={i,j};
				ans[i][j]='X';
			}
		}
	int x,y;
	for (int i=1;i<=n;++i)
		for (int j=1;j<=n;++j)
		{
			if (a[i][j][0]!=-1||ans[i][j]) continue;
			for (int k=0;k<4;++k)
			{
				x=dtx[k]+i;
				y=dty[k]+j;
				if (a[x][y][0]!=-1||ans[x][y]) continue;
				ans[i][j]=dvl[k];
				ans[x][y]=val[k];
				d[++t]={i,j};
				d[++t]={x,y};
				break;
			}
				
		}	
	while (h!=t)
	{
		nw=d[++h];
		for (int i=0;i<4;++i)
		{
			x=dtx[i]+nw.x;
			y=dty[i]+nw.y;
			if (a[x][y][0]==a[nw.x][nw.y][0]&&a[x][y][1]==a[nw.x][nw.y][1]&&!ans[x][y])
			{
				ans[x][y]=val[i];
				d[++t]={x,y};
			}
		}
	}
	for (int i=1;i<=n;++i)
		for (int j=1;j<=n;++j)
			if (!ans[i][j]) return printf("INVALID"),0;
	printf("VALID\n");
	for (int i=1;i<=n;++i,printf("\n"))
		for (int j=1;j<=n;++j) printf("%c",ans[i][j]);
	return 0;
}