AT_abc454_e [ABC454E] LRUD Moving 题解

题目传送门

思路

牛逼。首先一个 trick 是对棋盘进行黑白染色。接着我们会发现,每次移动一定会交换颜色,所以如果有一个点不能去,就可以推出有解的必要条件:\(n\) 为偶数,且 \((x + y)\) 为奇数。

接下来考虑构造得出这个条件的充分性。两列两列地分组,如果 \((x, y)\) 不在这两列中,就竖着蛇形排列;否则就横着蛇形排列。

代码

#include <bits/stdc++.h>
using namespace std;

int t, n, x, y;

void solve()
{
	scanf("%d%d%d", &n, &x, &y);
	if ((n & 1) || (!((x + y) & 1)))
	{
		printf("No\n");
		return;
	}
	printf("Yes\n");
	int a = 1, b = 1;
	for (int i = 1; i < (y + 1) / 2; i++)
	{
		for (int j = 1; j < n; j++) printf("D"), a++;
		printf("R"), b++;
		for (int j = 1; j < n; j++) printf("U"), a--;
		printf("R"), b++;
	}
	bool f = 0;
	for (int i = 1; i < n; i++)
	{
		if (i & 1)
		{
			if (f || (x == a && y - 1 == b)) printf("DR"), f = 1;
			else printf("RD");
			a++, b++;
		}
		else
		{
			if (f || (x == a && y + 1 == b)) printf("DL"), f = 1;
			else printf("LD");
			a++, b--;
		}
	}
	for (int i = (y + 1) / 2 + 1; i <= n / 2; i++)
	{
		printf("R"), b++;
		for (int j = 1; j < n; j++) printf("U"), a--;
		printf("R"), b++;
		for (int j = 1; j < n; j++) printf("D"), a++;
	}
	printf("\n");
}

int main()
{
	scanf("%d", &t);
	while (t--) solve();
	return 0;
}
posted @ 2026-04-25 17:10  lucasincyber  阅读(15)  评论(0)    收藏  举报