1 条题解
-
0
自动搬运
来自洛谷,原作者为

Field_Mouse
待灯灭,穷其一生跟随搬运于
2025-08-24 22:54:22,当前版本为作者最后更新于2024-05-25 20:00:00,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意简述
给定仅由 和 构成的字符串 和 ,你可以翻转 的子串,使得其子串中不包含 ,求最小操作次数,若无解输出 。
做法分析
一点思路没有,看数据范围。
发现 很小,并且部分分内贴心的给出了特殊的 。考虑分类讨论。显然我们并不在意哪个是 哪个是 ,只关心他们的相对位置。
记 。
显然看是否存在 ,存在即无解,否则输出 。
- 且
形如 ,我们发现最终结果一定可以形如 ,一次翻转可以将一个 翻转到后方,答案即为 串的个数。
- 且
形如 ,我们发现最终结果一定形如 ,对于任意两对 ,可以通过一次翻转操作拆散。但如果 的数量过半,则一定无解。答案即为 串的个数除以二上取整。
- 且形如
发现这类似于 ,答案就是出现次数除以二上取整。
- 且形如
同样,类似于 ,答案即为出现次数。
- 且形如
发现它也具有不对称的特点,同上,答案即为出现次数。
- 且形如
这位更是重量级。
我们发现,问题能够转化为让 中不存在连续的三个 。即通过翻转让 翻到 的中间去。为了不让 与其它的 接上,只有 中间或者 中间可以容纳 。
能容纳 个, 只能容纳 个。在操作次数相等的情况下,我们自然想要尽可能多的使用 ,所以可以想到一个贪心策略:尽可能的使用 ,在剩余不到 个或没有 后再使用 。正确性是显然的。
那就统计之后再讨论就好了。如果两种操作都不剩了,那就是无解。
细节看代码。
#include<bits/stdc++.h> #define AC return 0; #define pr(n) printf("%d",(n)) #define hh puts("") #define kg printf(" ") using namespace std; namespace fr{ int read() { int x=0,flag=1; char ch=getchar(); for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')flag=-1; for(;ch<='9'&&ch>='0';ch=getchar())x=(x<<3)+(x<<1)+ch-'0'; return flag*x; } } using namespace fr; string s,t; bool cmp(int a,int b){return a>b;} void sol1()//1 { char a=t[0]; for(auto i:s)if(i==a){puts("-1");return ;} puts("0"); } void sol2()//10 { int res=0; for(int i=0;i<s.size()-1;++i) { if(s.substr(i,2)==t)++res; } pr(res); } void sol3()//11 { char a=t[0]; int cnt=0,res=0; for(int i=0;i<s.size();++i) { if(s[i]==a) { ++cnt; if(i>0) { if(s[i-1]==s[i])++res; } } } if(cnt>(s.size()+1)>>1)pr(-1); else pr(res); } void sol4()//111 { vector<int> p; int res1=0,res2=0,cnt=0,now=0; bool flag1=0,flag2=0; string s1,s2; if(t[0]=='0')s1="11",s2="101"; else s1="00",s2="010"; for(int i=0;i<(int)s.size();i++) { if(s[i]==t[0])++now; else { p.push_back(now);now=0; if(i==0)res1+=1,flag1=1; if(!flag1&&i==1)res2+=1; if(i==(int)s.size()-1) { flag2=1,res1+=1; } if(!flag2&&s[(int)s.size()-2]!=t[0])res2+=1; if(i+1<s.size()) { if(s.substr(i,2)==s1)res1++; else if(i+2<s.size()) { if(s.substr(i,3)==s2)res2++; } } } } p.push_back(now); // cout<<res1<<" "<<res2<<endl; sort(p.begin(),p.end(),cmp); for(auto i:p) { if(i<3)continue; //if(i%2)continue; i-=2; // if(i==1&&res2){res2--;cnt++;continue;} if(res1>=(i>>1)){res1-=(i>>1);cnt+=(i>>1);i%=2;} else if(res1){i-=2*res1;cnt+=res1;res1=0;} if(!res2){res1-=(i+1)>>1;res2+=(i+1)>>1;}//没有101了可以尝试兑换一点11( cnt+=i; res2-=i; if(res2<0||res1<0){puts("-1");return;} } pr(cnt); } void sol5()//101 { int res=0; for(int i=0;i<(int)s.size()-2;++i) { if(s.substr(i,3)==t)++res; } res=(res+1)>>1; pr(res); } void sol6()//100&&110 { int res=0; for(int i=0;i<(int)s.size()-2;i++) { if(s.substr(i,3)==t)++res; } pr(res); } int main() { cin>>s;cin>>t; if(t.size()==1)sol1(); if(t.size()==2&&t[0]==t[1])sol3(); if(t.size()==2&&t[0]!=t[1])sol2(); if(t.size()==3&&t[0]==t[1]&&t[1]==t[2])sol4(); if(t.size()==3&&t[0]==t[2]&&t[0]!=t[1])sol5(); if(t.size()==3&&t[0]==t[1]&&t[1]!=t[2])sol6(); if(t.size()==3&&t[1]==t[2]&&t[0]!=t[1])sol6(); AC }
- 1
信息
- ID
- 9729
- 时间
- 1000ms
- 内存
- 1024MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者