AT_abc326_f Robot Rotation 题解
AT_abc326_f Robot Rotation 题解
经典问题,以前遇到过一个类似的问题:[ABC082D] FT Robot。
建议对比着看一看这两道题,是两种不同的思路。
(那一道题不用输出方案,因此可以用 bitset 优化;而此题需要输出方案,因此需要双向搜索。
思路
注意到每次只能「左转」和「左转」。
所以,偶数次走的只改变 \(x\) 坐标,奇数次走的只改变 \(y\) 坐标。
因此,我们可以将 \(x\) 方向和 \(y\) 方向的分开来看,然后在将这两部分合并。
然后考虑每个方向的是怎么算?
问题转化为:
给定序列 \(A\),可以改变任意元素的符号(正负),求一个方案,使得 \(\sum A=x\)。
显然,这是一个背包问题啦。
但是这样算来,复杂度是 \(n\times2^n\) 的,明显不可过。
再仔细看看问题,我们发现可以双向搜索!
我们将序列分为左、右两半部分,对于每部分,分别求解,即求出每部分在该坐标轴上可以做出的贡献的集合,然后看看两个集合中是否有和为 \(x\) 的。
但是本题似乎要输出方案?
发现方案最多有 \(25\) 位,于是使用状压。
对于二进制数 \(k\),我们规定,从后往前第 \(i\) 为表示 \(A_i\) 是否变成负数。
合并方案?我们进行操作的时候,是先操作左面的(前面的)。
因此我们将两个二进制数拼接在一起就可以了。
输出方案的时候,可以记录一个当前的方向,就很容易得出每次的转向了:
- 如果当前朝向«右»,接下来要往«上»走,则左转;
- 如果当前朝向«右»,接下来要往«下»走,则右转;
- (这个还用讲吗?。
注意:实现的时候,一定要注意二进制移位的细节!
时间复杂度:\(O(n\times2^{n/2})\)。
代码
评测记录:https://atcoder.jp/contests/abc326/submissions/47085159
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using ml = map<int, ll>;
#define endl '\n'
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rr read()
inline int read() {
int num = 0, flag = 1, ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') flag = -1;
for (; isdigit(ch); ch = getchar()) num = num * 10 + ch - '0';
return num * flag;
}
ml mean(vi x) {
ml ret[2]; ret[0][0] = 0ll;
int k = 0; rep(i, x.size()) {
ret[k ^= 1].clear(); for (auto t : ret[k ^ 1])
ret[k][t.first + x[i]] = t.second | (1 << i), ret[k][t.first - x[i]] = t.second;
} return ret[k];
}
ll solve(vi a, int x) {
int n = a.size();
vi L, R; rep(i, n) (i < n / 2 ? L : R).push_back(a[i]);
ml l = mean(L), r = mean(R);
for (auto i : l)
if (r.count(x - i.first)) return i.second | (r[x - i.first] << n / 2);
printf("No\n"), exit(0);
}
signed main() {
int N = rr, X = rr, Y = rr; vi x, y;
rep(i, N) (i & 1 ? x : y).push_back(rr);
ll a = solve(x, X), b = solve(y, Y);
printf("Yes\n");
int d = 1; rep(i, N) {
if (i & 1) putchar(((a >> i / 2) & 1) == d ? 'R' : 'L'), d = ((a >> (i >> 1)) & 1);
else putchar(((b >> i / 2) & 1) == d ? 'L' : 'R'), d = ((b >> (i >> 1)) & 1);
} return 0;
}
本文来自博客园,作者:RainPPR,转载请注明原文链接:https://www.cnblogs.com/RainPPR/p/solution-at-abc326-f.html
如有侵权请联系我(或 2125773894@qq.com)删除。