首页 > 其他分享 >YC323C [ 20240724 CQYC NOIP 模拟赛 T3 ] 手环(ring)

YC323C [ 20240724 CQYC NOIP 模拟赛 T3 ] 手环(ring)

时间:2024-08-19 11:15:13浏览次数:11  
标签:移动 NOIP int res 手环 T3 tp ++ include

题意

给定两个长为 \(n\) 的 \(0/1\) 串 \(A, B\)。

每次操作:

  • 对 \(A\) 向左或向右循环移位。
  • 选择 \(0 \le p < n \land B_i = 1\),则将 \(A_i\) 取反。

求将 \(A\) 变为 \(B\) 的最小操作次数。无解输出 -1

\(n \le 2000\)

Sol

显然无解当且仅当 \(A\) 和 \(B\) 不相同且 \(B\) 不存在 \(1\)。

考虑枚举一个终止状态 \(i\),表示 \(A\) 向右循环移动 \(i\) 位,且在过程中使用操作一将两串变成相等。

考虑移动 \(i\) 位后哪些位置不满足条件,不难发现事实上最优的决策一定满足先向左移动,然后向右移动到 \(i\) 右边,最后再移动回来。

原问题变为一个分配问题,每个移动 \(i\) 位后不满足条件的位置,需要向左或是向右找到一个 \(B_i\) 为 \(1\) 的位置消掉。

因此直接预处理出每个位置向左最近的 \(B_i\) 为 \(1\) 的位置,向右最近的位置。

这样直接对一维排序,倒着扫回来,动态维护另一维的最大值即可。

这里直接桶排,复杂度 \(O(n ^ 2)\)。

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#include <vector>
using namespace std;
#ifdef ONLINE_JUDGE

/* #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++) */
/* char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf; */

#endif
int read() {
    int p = 0, flg = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') flg = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        p = p * 10 + c - '0';
        c = getchar();
    }
    return p * flg;
}
void write(int x) {
    if (x < 0) {
        x = -x;
        putchar('-');
    }
    if (x > 9) {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}
bool _stmer;

const int N = 2e3 + 5;

char strbuf[N];

string s, h;

array <int, N> tpl, tpr;
array <vector <int>, N> isl;

int query(int n) {
    int ans = 2 * n;
    for (int i = 0; i < n; i++) {
        int res = 0, tp = i;
        for (int j = 0; j < n; j++)
            if (s[j] != h[(j + i) % n])
                isl[tpr[j]].push_back(j), res++;
        for (int j = n; j >= i + 1; j--) {
            for (auto k : isl[j])
                tp = max(tp, tpl[(k + i) % n]);
            ans = min(ans, (tp - i + j - 1) * 2 - i + res);
            /* if ((tp - i + j - 1) * 2 - i + res < 10) { */
                /* cerr << i << " " << tp << " " << j << "#" << endl; */
                /* for (auto k : isl[j]) */
                    /* cerr << k << "@@" << endl; */
                /* exit(0); */
            /* } */
        }
        for (int j = 0; j < n; j++) isl[j].clear();
    }
    return ans;
}

void solve() {
    scanf("%s", strbuf);
    s = strbuf;
    scanf("%s", strbuf);
    h = strbuf;

    int n = s.size(), tp = 0;
    for (auto k : h) tp += k - '0';
    if (s == h) return (void)puts("0");
    if (tp == 0) return (void)puts("-1");

    for (int i = 0; i < n; i++) {
        if (h[i] == '1') { tpl[i] = tpr[i] = 0; continue; }
        tpl[i] = tpr[i] = 1;
        while (h[(i - tpl[i] + n) % n] == '0') tpl[i]++;
        while (h[(i + tpr[i]) % n] == '0') tpr[i]++;
    }

    int ans1 = query(n), ans2 = 0;
    reverse(s.begin(), s.end()), reverse(h.begin(), h.end()), swap(tpl, tpr);
    reverse(tpl.begin(), tpl.begin() + n), reverse(tpr.begin(), tpr.begin() + n);
    /* cerr << endl; */
    ans2 = query(n);
    write(min(ans1, ans2)), puts("");
}

bool _edmer;
int main() {
    cerr << (&_stmer - &_edmer) / 1024.0 / 1024.0 << "MB\n";
    int T = read();
    while (T--) solve();
    return 0;
}

标签:移动,NOIP,int,res,手环,T3,tp,++,include
From: https://www.cnblogs.com/cxqghzj/p/18366946

相关文章

  • SpringBoot3核心特性-快速入门
    目录传送门前言一、简介1、前置知识2、环境要求3、SpringBoot是什么二、快速体验1、开发流程2、特性小结3、SpringInitializr创建向导三、应用分析1、依赖管理机制2、自动配置机制2.1、初步理解2.2、完整流程2.3、如何学好SpringBoot四、核心技能1、常用注解1.1、......
  • 演唱会上万根荧光手环同步控制,它是怎么做到的?
    背景参加海山日月音乐节,对于现场上万的荧光手环,如何能做到同步控制灯光的颜色,和闪动频率,很是好奇,特此研究了一下。原理荧光棒内部电路由两块PCB呈L字形拼接而成。其中,主板为荧光棒的灯光控制电路,主要负责控制拼接小板上RGB灯珠的工作状态切换,实现着色、闪烁等多种灯光效果。而......
  • 洛谷P1020 [NOIP1999 提高组] 导弹拦截(未完)
    传送门:P1020[NOIP1999提高组]导弹拦截题目大意:一个拦截导弹的系统,每次只能拦截高度不超过上一个的导弹求出:一个系统最多能拦截的导弹数量;要拦截所有导弹最少需要的该系统的数量。思路:第一问:一眼就是最长单调不上升子序列,朴素DP求解,复杂度为O(n^2);请参考,能过掉50%......
  • 洛谷P1983 [NOIP2013 普及组] 车站分级 题解
    思路由题可知,在一趟车次的区间内,停靠的站点的等级恒大于不停靠的站点。因此,对于每一趟车次的区间,给所有停靠的站点向所有不停靠的站点两两连有向边,然后求图中最长的路径长度,就能得到答案。实现因为可能出现重边,而且\(n\le1000\),所以在处理车次连边的时候使用邻接矩阵,再改成邻......
  • 洛谷P1083 [NOIP2012 提高组] 借教室 && 差分学习笔记
    传送门:P1083[NOIP2012提高组]借教室"八骏日行三万里,穆王何事不重来。"可惜啊,他再也没有回来……题目大意:给你每天能够租借的教室数量和几份租借申请每份申请包含租界时间(从第几天到第几天)和每天需要租借的教室数量问你能否满足所有的租借要求,如果不能,驳回一份最前......
  • P1002 [NOIP2002 普及组] 过河卒
    题目描述棋盘上 A 点有一个过河卒,需要走到目标 B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。棋盘用坐标表示,A 点 (0,0)、B 点 (n,m),同样马的位置坐......
  • 基于SpringBoot3框架-数据库乐观锁、悲观锁、Redis、Zookeeper分布式锁的简单案例实现
    1.分布式锁的定义分布式锁是一种在分布式系统中用来协调多个进程或线程对共享资源进行访问的机制。它确保在分布式环境下,多个节点(如不同的服务器或进程)不会同时访问同一个共享资源,从而避免数据不一致、资源竞争等问题。2.分布式锁的工作原理分布式锁的工作原理与单机锁......
  • Study Plan For Algorithms - Part3
    1.最长回文子串题目链接:https://leetcode.cn/problems/longest-palindromic-substringm/给定一个字符串s,找到s中最长的回文子串classSolution:deflongestPalindrome(self,s:str)->str:defexpand_around_center(left,right):whileleft......
  • P1045 [NOIP2003 普及组] 麦森数极简解法解读
    源代码如下(这个精妙绝伦的算法不是我发现的,而是取自原题解中的某个大佬,在经过一顿学习正常题解后看到,顿觉豁然开朗,原贴:https://www.luogu.com.cn/article/c3u874kg)includeincludeincludeusingnamespacestd;longlonga[501]={1};intmain(){intp;cin>>p;cout<<(......
  • [2027届]NOIP2024模拟赛#3
    老规矩,先放榜。打的还行。T1一眼想到按照字典序排序。然后想到了同学slay.one的号AAaz,于是想看看aaaz和aaa的顺序。不试不知道,一试吓一跳,萎了。然后想到特判,发现bbba和bbb又萎了。然后一瞬间想到哈希看到排序的恶心程度很像之前的一个ABC-F。突然发现按照那道......