题解 AT4432 【[ARC103B] Robot Arms】
大概是给出了和cyj不同的另一种证明方法和另一种构造方式?但其实本质是一样的。
首先无解很容易判断。因为多走一步和少走一步之间的差值总是
发现这个题的本质是拆分问题。那么大概可以引导到「二进制拆分」这种泛式的拆分方式上。不妨考虑对于一组
1、只是单纯地拿掉几个元素。比如
2、拿出几个元素并且换进去几个元素。比如
可以看出,这是可以相互通达的。
更详细一点。因为对于四个象限,情况都是等价的。所以只考虑第一象限。发现对于
到这一步就已经很完美了,但是依然存在问题。如果
实现方面,发现最合法区域后是个内部镂空的菱形。找出来之后,对于一组坐标
int n ;
int cnt ;
int _eve ;
ll nx, ny ;
int bc[N] ;
struct rg{
int l ;
int r ;
int t ;
}base[N] ; //D R U L
int dx[4] = {0, 1, 0, -1} ;
int dy[4] = {-1, 0, 1, 0} ;
char s[4] = {'U', 'L', 'D', 'R'} ;
int main(){
cin >> n ;
bc[0] = 1 ;
for (int i = 1 ; i <= n ; ++ i){
cin >> base[i].l >> base[i].r ;
base[i].t = abs(base[i].l + base[i].r) & 1 ;
}
for (int i = 2 ; i <= n ; ++ i)
if (base[i].t != base[1].t) return puts("-1"), 0 ;
for (int i = 1 ; i <= 30 ; ++ i) bc[++ cnt] = 1 << i ;
cout << cnt + 1 + (bool)(!(base[1].t & 1)) << '\n' ;
if (!(base[1].t & 1)) cout << 1 << " " ;
for (int i = cnt ; ~i ; -- i) printf("%d%c", bc[i], " \n"[!i]) ;
for (int i = 1 ; i <= n ; ++ i){
nx = base[i].l ;
ny = base[i].r ;
if (!(base[i].t & 1))
ny -= 1, putchar('U') ;
//cout << nx << " " << ny << endl ;
for (int j = cnt ; ~j ; -- j){
for (int k = 0 ; k < 4 ; ++ k){
ll kx = nx + (ll)dx[k] * bc[j] ;
ll ky = ny + (ll)dy[k] * bc[j] ;
if (abs(kx) + abs(ky) < bc[j]){
nx = kx ; ny = ky ;
//cout << nx << " " << ny << endl ;
printf("%c", s[k]) ; break ;
}
}
}
puts("") ;
}
return 0 ;
}