首页 > 其他分享 >P11361 [NOIP2024] 编辑字符串

P11361 [NOIP2024] 编辑字符串

时间:2024-12-01 15:10:57浏览次数:10  
标签:字符 匹配 任意 ll cin 字符串 textcolor P11361 NOIP2024

题目大意

详细题目传送门
两个 \(01\) 串,可以对两个串中任意相邻的字符进行交换,没有代价可以进行任意多次。可是两个串有的位置的字符是定死的,无法被交换,求任意次操作后最多让两个串的多少个位置 \(01\) 相等。即 \(\sum [a_i=b_i]\)。

\(n\leq 10^5\)

思路

首先根据冒泡排序的性质,假设 \([l,r]\) 内的所有字符都可以被交换,那么这里的所有字符可以排成任意一个排列。

然后我们就可以将本题转成将两个串分成一些连通块,上下排列,每个块内可以按照任意顺序进行排列,求最多相等。

感觉就像是可以贪心的样子。先去考虑能不能假定固定一个串,只动第二个。发现明显不行,如果是形如

\[\textcolor{red}{AAA}\textcolor{blue}{BBBBB}\textcolor{green}{CCCC} \]

\[\textcolor{red}{A}\textcolor{blue}{BBBB}\textcolor{green}{CCCCCCC} \]

的情况,我们可能会需要将第二个串的一些数字运到第一个串的红色位置才是匹配最优秀的。所以两个串必须联动。

因为是 NOIP 的第一题,应该不会出一些动规类的东西,所以还是向贪心方向考虑。发现任意一个字符只要匹配上了就赚了,不存在让位情况。考虑证明:

反证法对于一个数字 \(A\),假设在可以匹配的情况下不去进行匹配,而是让位,则必然浪费一个位置无法进行匹配。如果让别的数字 \(B\) 也在这里匹配则若匹配成功就必有 \(A=B\)。又根据上文冒泡排序性质我们可以构造出一个排列使 \(B\) 移动到匹配位,让 \(A\) 移动到 \(B\) 原位,则与直接用 \(A\) 匹配无异。
若不去匹配 \(A\) 一开始能够匹配的位置,而是换了一个不同字符的在上面,则这个位置就无法贡献答案。即便 \(A\) 能够在后面匹配,也只是回到起点,而原本能够匹配的不同字符也有可能无法匹配上,答案一定不优。

这样我们就可以发现可以按从左到右的位进行考虑。对于当前两个字符所属的连通块,如果还有能够匹配的字符,就移动过来,将两个连通块匹配的这个的这个字符数量各自减 \(1\),让答案加 \(1\) 即可。

代码

#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
const ll MAXN=2e5+5;
string a,b,p,q;
ll T,n;
ll id[2][MAXN],num[2][MAXN][2];
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>T;
    while(T--){
        memset(num,0,sizeof(num));
        memset(id,0,sizeof(id));
        cin>>n;
        cin>>a>>b>>p>>q;
        a=" "+a,b=" "+b,p=" "+p,q=" "+q;
        ll tot=0;
        for(int i=1;i<=n;++i){
            if(i==1||p[i]=='0'){
                tot++;
                num[0][tot][a[i]-'0']++;
                id[0][i]=tot;
                if(p[i]=='0'&&p[i+1]!='0'){
                    tot++;
                }
                continue;
            }
            num[0][tot][a[i]-'0']++;
            id[0][i]=tot;
        }
        tot=0;
        for(int i=1;i<=n;++i){
            if(i==1||q[i]=='0'){
                tot++;
                num[1][tot][b[i]-'0']++;
                id[1][i]=tot;
                if(q[i]=='0'&&q[i+1]!='0'){
                    tot++;
                }
                continue;
            }
            num[1][tot][b[i]-'0']++;
            id[1][i]=tot;
        }
        ll ans=0;
        for(int i=1;i<=n;++i){
            if(num[0][id[0][i]][0]&&num[1][id[1][i]][0]){
                ans++;
                num[0][id[0][i]][0]--;
                num[1][id[1][i]][0]--;
            }else if(num[0][id[0][i]][1]&&num[1][id[1][i]][1]){
                ans++;
                num[0][id[0][i]][1]--;
                num[1][id[1][i]][1]--;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

标签:字符,匹配,任意,ll,cin,字符串,textcolor,P11361,NOIP2024
From: https://www.cnblogs.com/tanghg/p/18579809/solution-P11361

相关文章

  • 洛谷P11361 [NOIP2024] 编辑字符串
    ProblemSolve首先任意更换相邻元素任意次等同于在可交换范围内随便移动这题是求最优解,直观想到DP和贪心,但是容易反应过来本题DP的话很难做到无后效性,且状态较多,故尝试贪心不难发现,我们从左往右遍历的某个时刻进行交换后所得到的局部最优解总是答案的一种方案的一部分原因......
  • NOIP2024游寄
    Day-2赛前最后一场模拟赛,教练说要打压一下我们心态,找了一套特别无语的题让我们做,虽然数据水,但我还是没有到\(100pts\),心态确实挺炸裂的(考前还在保佑NOIP不会出这样的毒瘤题)Day-1早上想复习,就开始带动全机房的人民学习模拟退火。(甚至还去网上找了几个大冤种一起写)然后下午睡......
  • 使用js写一个计算字符串的字节数的方法
    functiongetByteLength(str){letbyteLength=0;for(leti=0;i<str.length;i++){constcharCode=str.charCodeAt(i);if(charCode<=0x007f){byteLength+=1;}elseif(charCode<=0x07ff){byteLength+=2;......
  • NOIP2024 游记
    NOIP2024赛后总结突发情况刚来到座位,开始试机!但是我只定义了个变量同时读入后再输出——发现运行了将近\(10\)秒钟左右,还把Dev-C++给卡得未响应了?!想起之前看到李易同学长的NOIP游记,这也太类似了吧,赶紧找监考老师换了一台电脑,但是好像还是有点慢,那就算了吧!(后来好像用着用......
  • NOIP2024 游记
    开题,先看A的特殊性质,然后很快就有了正解思路。写加调,还好这个机子安装了单步调试,很快就调完了但还是错,有点慌。5分钟瞪出两个错误,然后9:11过T1,2分钟检查,希望别挂。开T2,刚开始以为是推性质DP题,后来发现直接乘法原理就行,40分钟才写完。看到T3,感觉不太能做,T4瞄了一眼......
  • 神秘回忆录——我的NOIP2024游记
    前言我,厦门外国语学校(\(\text{XMFLS}\))高一历史上最菜的一位\(\text{OIER}\)。在刚刚结束不久的\(\text{CSP-S2024}\)中,获得了300pts的低分成绩,侥幸的获得了\(\text{NOIP2024}\)的参赛资格。我对此感到十分的荣幸,并写下这篇游记。回首过往,我从神秘\(\text{YLSX}\)接触......
  • noip2024
    NOIP2024游记考试之前一直有很多话想在游记里说,但考完后又不知道该说些什么。这六个月的集训时光仿佛像一场梦一般。怒砍\([60,100]+0+0+0\)作为一个只学了不到一年的OIer,我知道这不是理由,noip考爆炸了,本来定的策略是稳切第一题,后面三题骗分,能混个省二或省一。只是没......
  • The solution to NOIP2024·T1——edit
    ThesolutiontoNOIP2024·T1——edithttps://www.luogu.com.cn/problem/P11361这是我在赛场想出来的思路,平时一个绿题都写不出来的题竟然一眼出思路,也真是RP++;思路由题目中的非限制的数可以互相交换,想到对于每一段连续的非限制性的区间都可以任意排布位置。那么可以把t序......
  • NOIP2024 游寄
    NOIP2024Day0最后抱佛脚,教练让我们看点双边双,才发现原来我只写过强连通分量的Tarjan,写了几个模板。在本校考,所以去机房试机,擦了以下设备。发现学校机房电脑居然是十代i5。内存加到16G了,应该不会再像CSP2023和CSP2024开考半小时死机了。准考证号90+,感觉1=渺茫。Day1出门忘......
  • 编一个程序,从键盘上输入一串符号(以回车键为结束),将其以字符串形式存入一维字符数组,然后
    大学作业,运行不了就把每个for循环里面的int提出来,括号内保留i就行了!!!!!多的我不说了,代码放地下自取自拿,某人在这里求个赞,陆续会更新实验3-5,所有作业都有复制(自取)版和详解版,记得关注,谢谢各位:tips:gets在C11版本被删去,目前仅仅是用于大学计算机,正式版我也放在末尾并说明区别自取版:......