本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
题目链接
题目
题目大意
一个游戏里有 行 列的地图,地图的每个格子上都有一个字符,格子 中可能出现的字符及其含义如下:
- ‘X’:到达格子 后游戏结束。
- ‘U’:到达格子 后应该向上走,去 。
- ‘D’:到达格子 后应该向下走,去 。
- ‘L’:到达格子 后应该向左走,去 。
- ‘R’:到达格子 后应该向右走,去 。
给出以每个格子为起点出发将在哪个格子游戏结束,如果从该格子出发游戏永远不停止将会给出 ,试判断输入是否描述了一张合法的游戏地图。如果合法,输出任何满足描述的游戏地图。
思路
首先我们考虑哪些信息是已知可以填到地图上的——如果一个格子的坐标和它的结束游戏位置相同,那么该格子的值一定是 ‘X’;如果有两个相邻的格子以他们为起点将永远不会结束游戏,那么它们可以直接被设置为环路。
向所有已经填入信息的格子 的上下左右方向扩展,如果与其相邻的格子 与 结束游戏格子相同,就让 的下一步走向 ,即填上 的答案。
代码
#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;
}