首页 > 其他分享 >AT_abc326_f Robot Rotation 题解

AT_abc326_f Robot Rotation 题解

时间:2023-10-31 10:23:57浏览次数:57  
标签:ch 题解 Robot ret abc326 num using 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;
}

标签:ch,题解,Robot,ret,abc326,num,using,Rotation
From: https://www.cnblogs.com/RainPPR/p/solution-at-abc326-f.html

相关文章

  • AT_abc325_f Sensor Optimization Dilemma 题解
    AT_abc325_fSensorOptimizationDilemma题解Date20231025:修复手滑公式\(\min\)、\(\max\)写反了。动态规划。类似背包问题。朴素算法记\((x,y)\)表示使用\(x\)个(1)传感器、\(y\)个(2)号传感器。设\(f(t,i,j)\)表示覆盖前\(t\)个区间,使用\((i,j)\)传感......
  • AT_abc325_g offence 题解
    AT_abc325_goffence题解一道不难但是需要想一想的区间DP。有一个比较复杂的例子:ooofofxxx,简单的分析可知,一个of后面删除多少,与其前、后都有关,于是考虑区间DP。想到这里,其实问题已经解决一半了。状态设计设\(f(l,r)\)为闭区间\([l,r]\)经过操作之后的最小长度。注......
  • [CSP-S2020] 儒略日 题解
    [CSP-S2020]儒略日今儿终于做掉困扰多年的题目了,其实想好细节也不难。容易发现儒略历和格里高利历的润年判断方式不一样,并且中间有消失的十天,计算起来相当不方便。所以我们可以首先计算出\(-4713.1.1\)~\(1582.10.4\)会经过多少天,可以通过一天一天暴力跳的方法计算出需要\(......
  • P4309 [TJOI2013] 最长上升子序列题解
    P4309[TJOI2013]最长上升子序列题解正文单调队列?单调锤子队列!!本题的操作可以省略成:单点修改区间查询好极了,此时我们有两种选择:线段树和树状数组,(平衡树,真不会,下一位因为不需要其他操作,所以我们还是选择更小巧更可爱的树状数组吧。关于vectorvector的insert操作支......
  • Atcoder Beginner Contest 326 (ABC326)
    不知道为什么拖到现在,我是摆怪。A.2UP3DOWN模拟,略。B.326-likeNumbers模拟,略。C.Peak双指针板子。D.ABCPuzzle基础dfs。但是赛时不知道为什么觉得状态数不会很少,于是写了一个巨大复杂的状压。这里粗略算算有效状态数:仅考虑每行的限制,有\(\binom{3}{5}=10\)种选......
  • 题解 ABC326G【Unlock Achievement】
    题解ABC326G【UnlockAchievement】problem有\(n\)项属性,第\(j\)个属性的等级\(l_j\)初始为\(1\),每提升一级花费\(c_j\)的钱。又有\(m\)项成就,第\(i\)项成就要求对于所有\(1\leqj\leqn\),都要\(l_j\geqL_{i,j}\),如果满足所有要求,获得\(a_i\)的钱。求你最多......
  • ADASTRNG - Ada and Substring 题解
    ADASTRNG-AdaandSubstring题解题目描述给定一个小写字符串。输出\(26\)个数,代表以\(\texttt{a}\sim\texttt{z}\)开头的本质不同的子串个数。题目分析高度数组模板题。可以想到将以每个字符开头的本质不同的子串数目转化为:以每个字符开头的所有字串数目减去以每......
  • Luogu P4168 [Violet] 蒲公英 题解
    题目链接[Violet]蒲公英分析可以先将\(a[i]\)离散化然后考虑分块对于询问\(x,y\),\(x\)属于\(p\),\(y\)属于\(q\)当\(q-p<=1\)时直接暴力枚举即可,时间复杂度为\(O(\sqrt{n})\)\(else\)如图中间为分好块的地方我们发现,\(ans\)只可能为中间的众数或两边的......
  • 2023年10月第四周题解------输入与输出
     问题A:ly喜欢玩石头 解题思路题目告诉我们(1<=a,b<=1e9),那么int类型就够了。因为这两个数相加最大为20亿定义两个变量a和b输入a和b的值打印a加b的值#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>#include<time.h>intmain......
  • 题解:「NOIP2022 提高组」种花
    题解:「NOIP2022提高组」种花题目大意:给定一个\(n\timesm\)的01矩阵,0表示可以种花,1表示土坑(无法种花),现在要在图上种出一个C型或F型(C,F横着的两条线的长度都可以不同,但一定是面向右边的),现在问你种C和F分别有多少种方案(除了这个形状外不能在任何地方种花),多组数据,\(T\leq5\)。......