AtCoder Regular Contest 103~107

AtCoder Regular Contest 103

D. Robot Arms

不合法情况显然只有两个点奇偶性不同时才会出现。

考虑构造,首先假如构造出了一个序列,显然一种贪心策略是往最接近的方向跳。

可以证明当序列为 \(\{2^i\}\) 时,可行的解覆盖所有奇偶性相同的点。

那么直接往近的方向跳,可以发现第 \(i\) 步后两点距离不会超过 \(\{2^i\}\),所以是正确的。

最后注意特判奇偶性,如果为奇额外加一个 \(1\)

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1010
#define ll long long
using namespace std;
int x[N],y[N];
int d[N];
ll dis(ll x0,ll y0,int t){return abs(x0-x[t])+abs(y0-y[t]);}
const char opt[]="LRDU";
int main()
{
    int n;
    scanf("%d",&n);
    int m=0;
    d[++m]=1<<30;
    for(int i=30;i>=0;i--) d[++m]=1<<i;
    d[++m]=1;
    for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
    for(int i=2;i<=n;i++) if((x[i-1]%2+y[i-1]%2+2)%2!=(x[i]%2+y[i]%2+2)%2){puts("-1");return 0;}
    if((x[1]%2+y[1]%2+2)%2) d[++m]=1;
    printf("%d\n",m);for(int i=1;i<=m;i++) printf("%d\n",d[i]);
    for(int i=1;i<=n;i++)
    {
        ll x0=0,y0=0;
        for(int j=1;j<=m;j++)
        {
            ll di=dis(x0-d[j],y0,i),id=0;
            if(dis(x0+d[j],y0,i)<di) di=dis(x0+d[j],y0,i),id=1;
            if(dis(x0,y0-d[j],i)<di) di=dis(x0,y0-d[j],i),id=2;
            if(dis(x0,y0+d[j],i)<di) di=dis(x0,y0+d[j],i),id=3;
            putchar(opt[id]);
            if(id==0) x0-=d[j];
            if(id==1) x0+=d[j];
            if(id==2) y0-=d[j];
            if(id==3) y0+=d[j];
        }
        puts("");
        // printf("%lld %lld %d %d\n",x0,y0,x[i],y[i]);
        if(x0!=x[i] || y0!=y[i]) throw;
    }
    return 0;
}

AtCoder Regular Contest 104

AtCoder Regular Contest 105

AtCoder Regular Contest 106

AtCoder Regular Contest 107

posted @ 2021-09-13 11:28  Flying2018  阅读(9)  评论(0)    收藏  举报