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;
}

浙公网安备 33010602011771号