[NC记录]AT4432 [ARC103B] Robot Arms

command_block

2021-05-17 10:53:19

Personal

**题意** : 给定 $n$ 个坐标 $(x_i,y_i)$。 构造长度为 $m$ 的序列 $\{c_{1\sim m}\}$ ,满足: - $c_i$ 表示第 $i$ 步「步长」。 - 对于每个坐标,从 $(0,0)$ 开始走,共走 $m$ 步。第 $i$ 步可以让 $(x,y)$ 变成 $(x±c_i,y)$ 或 $(x,y±c_i)$ 。 - 走完 $m$ 次之后,恰好走到这组坐标。 - 要求 $m\leq 40,c_i\leq 10^{12}$ 。 给出 $\{c_{1\sim m}\}$ 的具体值,以及每个坐标的行动方向序列。或指出无解。 $n\leq 10^3,x_i,y_i\leq 10^9$ ,时限$\texttt{2s}$。 ------------ 不难发现,最终到达的点的 $x+y$ 的奇偶性是相同的。故若给定的坐标中 $x+y$ 的奇偶性有不同,则无解。 观察下列图像,图中 `i` 是走第 $i$ 步能到达的范围 : ```cpp ....... ....... ...1... ..101.. ...1... ....... ....... ``` $c=\{1\}$。 ```cpp ...2... ..212.. .2.2.2. 2120212 .2.2.2. ..212.. ...2... ``` $c=\{2,1\}$。 不难发现,只需令 $c=\{2^m,2^{m-1},...,1\}$ ,就能达到 $O(2^m)$ 以内的任何 $x+y$ 为奇数的位置。 若要到所有 $x+y$ 为偶数的位置,则在 $c$ 后面再加一个 $1$ 即可。 最后考虑如何构造方向方案。 对于四种方向,走向离目的地曼哈顿距离最小的一个。不难理解正确性。 ```cpp #include<algorithm> #include<cstdio> #define ll long long #define MaxN 1050 using namespace std; ll x[MaxN],y[MaxN],c[MaxN]; int n,m; int main() { scanf("%d",&n); int o=0; for (int i=1;i<=n;i++){ scanf("%lld%lld",&x[i],&y[i]); o+=(x[i]+y[i])&1; } if (o!=0&&o!=n){puts("-1");return 0;} for (int i=35;i>=0;i--)c[++m]=1ll<<i; if (!o)c[++m]=1; printf("%d\n",m); for (int i=1;i<=m;i++) printf("%lld ",c[i]);puts(""); for (int i=1;i<=n;i++){ ll sx=0,sy=0; for (int k=1;k<=m;k++){ ll tx,ty,sav=1ll<<60,tx2,ty2; char op; tx=sx+c[k];ty=sy; if (abs(x[i]-tx)+abs(y[i]-ty)<sav){ op='R'; sav=abs(x[i]-tx)+abs(y[i]-ty); tx2=tx;ty2=ty; } tx=sx-c[k];ty=sy; if (abs(x[i]-tx)+abs(y[i]-ty)<sav){ op='L'; sav=abs(x[i]-tx)+abs(y[i]-ty); tx2=tx;ty2=ty; } tx=sx;ty=sy+c[k]; if (abs(x[i]-tx)+abs(y[i]-ty)<sav){ op='U'; sav=abs(x[i]-tx)+abs(y[i]-ty); tx2=tx;ty2=ty; } tx=sx;ty=sy-c[k]; if (abs(x[i]-tx)+abs(y[i]-ty)<sav){ op='D'; sav=abs(x[i]-tx)+abs(y[i]-ty); tx2=tx;ty2=ty; }putchar(op); sx=tx2;sy=ty2; }puts(""); }return 0; } ```