1. 程式人生 > >AtCoder Regular Contest 103 D. Robot Arms

AtCoder Regular Contest 103 D. Robot Arms

題意:

給n個點,座標範圍1e9, 讓你構造出m條邊,(m <= 40)每條邊可以有上下左右四個方向,長度 < 1e12,目的是這m條邊可以達到任意一個點(respectively),問能不能構造出來,能就輸出,不能輸出-1.

解題思路:

首先容易想到輸出-1的情況,每個點橫縱座標相加的奇偶性得是一樣的,不然構造不出來

能構造出來的情況:

不妨假設座標和為奇數

選出這些邊:{1, 2, 4, 8, ... , 2 ^ k },先考慮只有1的情況,可到達點(0, 1), (1, 0), (0, -1), (-1, 0),加上2,可加上到達(0, 3), (0, -3), (3, 0), (-3, 0), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1),畫出來,發現是頂點為(3, 0), (-3, 0), (0, 3), (0, -3)的正方形上的所有整點。

By induction, 有了這些點,可以到達頂點為(2^(k+1)−1,0),(−2^(k+1)+1,0),(0,2^(k+1)−1),(0,−2(^k+1)+1)上的所有整點。

剛剛假設了座標和為奇數,對於偶數,只需要加一個邊長為1的邊即可。

然後貪心邊長從長到短來安排方向即可

Ac Code:

#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define lowbit(x) x&(-x)
#define PII  pair<int, int> 
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const ll inf = 1e18;
const int mod = (int)1e9 + 7;
const int maxn = (int)1e3 + 5;
using namespace std;
 
#define int ll
 
struct node{
	int x, y;
}a[maxn];
 
int d[50];
int dir[4][2] = { {-1, 0}, {1, 0}, {0, 1}, {0, -1} };
string s = "LRUD";
int n, cnt = 0;
 
int dis(int x1, int y1, int x2, int y2){
	return abs(x1 - x2) + abs(y1 - y2);
}
 
void work(int x, int y){
	node now;
	now.x = now.y = 0;
	for(int i = 1; i <= cnt; i++){
		int Min = inf;
		int pos = 0;
		for(int j = 0; j < 4; j++){
			int tx = now.x + dir[j][0] * d[i], ty = now.y + dir[j][1] * d[i];
			int t = dis(tx, ty, x, y);
			if(Min > t) Min = t, pos = j;
		}
		now.x += d[i] * dir[pos][0], now.y += d[i] * dir[pos][1];
		putchar(s[pos]);
	}
	puts("");
}
 
int32_t main()
{
	scanf("%lld", &n);
	for(int i = 1; i <= n; i++){
		scanf("%lld %lld", &a[i].x, &a[i].y);
		if((abs(a[i].x + a[i].y) & 1) != (abs(a[1].x + a[1].y) & 1)) return 0 * puts("-1");
	}
	for(int i = 30; i >= 0; i--){
		d[++cnt] = 1 << i;
	}
	if((a[1].x + a[1].y) % 2 == 0) d[++cnt] = 1;
	printf("%lld\n", cnt);
	for(int i = 1; i < cnt; i++)
		printf("%lld ", d[i]);
	printf("%lld\n", d[cnt]);
	for(int i = 1; i <= n; i++){
		work(a[i].x, a[i].y);
	}
	return 0;
}

over