AtCoder Regular Contest 103 Problem D Robot Arms (构造)

时间:2023-03-09 17:55:53
AtCoder Regular Contest 103  Problem D  Robot Arms (构造)

题目链接  Problem D

给定$n$个坐标,然后让你构造一个长度为$m$的序列,

然后给每个坐标规定一个长度为$m$的序列,ULRD中的一个,意思是走的方向,

每次从原点出发按照这个序列方向,每次走的距离是对应位置的那个值,

最后要走到那个坐标。

直接构造,无解的条件是$x$和$y$的和奇偶性不全相等。

我当时想不出来是因为感觉两个方向不好控制,结果其实可以用二进制统一操作。

如果和是偶数那么加一个往右走一个的单位的操作转化为奇数就行。

然后按照二进制的方法从小到大一个个转换,就像转二进制那样。

接下来输出就好了。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second typedef long long LL; const int N = 1e3 + 5; int a[N], b[N];
int n, m, c, fg;
char s[45]; int main(){ scanf("%d", &n);
c = 0; rep(i, 1, n){
scanf("%d%d", a + i, b + i);
if ((a[i] + b[i]) & 1) ++c;
else --c;
} if (abs(c) != n) return 0 * puts("-1"); m = 31 + (c < 0); printf("%d\n", m);
rep(i, 0, 30) printf("%d ", 1 << i);
if (c < 0) putchar(49);
putchar(10); rep(i, 1, n){
int x = a[i], y = b[i];
if (c < 0) s[31] = 'R', --x;
fg = 0;
dec(j, 30, 0){
if (abs(x) < abs(y)) swap(x, y), fg ^= 1;
if (x > 0) x -= 1 << j, s[j] = fg ? 'U' : 'R';
else x += 1 << j, s[j] = fg ? 'D' : 'L';
} puts(s);
} return 0;
}