1. 程式人生 > >AtCoder Regular Contest 103 Problem D Robot Arms (構造)

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

https con 進制 bsp code lap 直接 coder efi

題目鏈接 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;
}

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