[Codeforces Round #794 (Div. 2)] D. Linguistics
我是什么东西艹艹艹
《我离正解只差个sort》
首先,观察字符串,可以发现:若存在形似\(AA……BB\)或\(BB……AA\)等有两个相同的字符挨在一起的情况,则我们在它们中间放一块隔板
\(BAABBABBAA\rightarrow\) \(BA\) \(AB\) \(BAB\) \(BA\) \(A\)
$ABABABBAABAB\rightarrow $ \(ABABAB\) \(BA\) \(ABAB\)
那么,位于同一区间的所有字符都是\(AB\)相间的形式,也就是说,可以用碎片\(AB\)和\(BA\)来拼凑出它们
当某一区间的字符个数为奇数时,如\(ABA\),若想使用\(AB\)或\(BA\),则一定会删去一个\(A\),而具体是哪一个\(A\),并不用关心(删去不同的\(A\),则会导致用于表示这一区间的碎片不同,后文会具体提到)
称一个区间最理想的使用碎片的情况(即全用一种碎片拼凑出整个区间)为一个区间使用的碎片
当某一区间的字符个数为偶数时,如\(ABABABABAB\),那么最理想的情况是用五个\(AB\)来凑这段区间,而当我们\(AB\)不够用的时候,设当前只有两个\(AB\),则可以将原区间用\(ABAB\),\(A\),\(BABA\),\(B\)拼凑出来
也就是说,当前区间为偶数时,可以通过使用一个\(A\)与\(B\)来使得区间使用的碎片发生变化
综上,可以发现,当区间为奇数时,它使用的碎片是不确定的,而当区间为偶数时,它使用的碎片是确定的(偶区间使用的碎片可以使用\(A\)与\(B\)来改变)
所以,我们先处理区间为偶数时的情况,因为这时使用的碎片确定
当有多个偶数区间使用的碎片都为\(AB\)时,举个例子:
\(AB\) \(AB\) \(ABABABAB\) \(ABABABABAB\)
我们将这些区间按照大小从小到大排序,因为\(AB\)不一定能都填满所有的区间,所以我们从长度小的区间开始填,这样,我们就能保证被填满的区间最多,而没有填满的区间使用\(A\)和\(B\)来进行转换其使用的碎片,这样就能确保我们使用的\(A\)和\(B\)尽可能少
原因:对于我们仅有的\(A\),\(B\),它们可以用来更改区间使用的碎片以及填充区间,既其能够使用的情况与其作用是远远大于\(AB\)和\(BA\)的,所以我们希望\(A\),\(B\)能够尽可能多的剩下
在我们解决完偶区间后,我们考虑奇区间
首先,若当前区间为\(AB……BA\)的形式,则用一个碎片\(A\)替代最前面或最后面的\(A\)(相当于删去最前面或最后面的\(A\)),这样就能使用\(AB\)或\(BA\)去填满这个区间
$ABABABABABA\rightarrow $ \(A\) \(BABABABABA\)
而若我们剩下的\(AB\)或\(BA\)不能靠自己这一类去填满当前区间,也就是我们需要用\(AB\)和\(BA\)两种碎片给来拼凑同一区间,则我们将碎片\(A\)替代的字符变成区间中一个非端点的\(A\),此时区间被划分成了两半,左边一半使用的碎片为\(AB\),右边一半使用的碎片为\(BA\)
\(ABABABABABA\rightarrow\) \(ABAB\) \(A\) \(BABABA\)
综上,对于奇区间,无论怎样用\(AB\)和\(BA\)拼凑,都只需要用一个\(A\)或\(B\),所以我们只需要在偶区间操作完后再判断一下\(A/B\)的数量+\(AB\)的数量+\(BA\)的数量是否能填满奇区间即可
对于\(A/B\):若我们先将奇区间中使用的单个A和B删去后,A和B的数量一定是相等的,因为它们在偶区间中的使用是成对出现的
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int a,b,c,d,n,cnt1,cnt2,qk[N],tot;
int sum,sum1,sum2;
char s[N];
vector<int> t1,t2;
int main(){
int T;
scanf("%d",&T);
while(T--){
cnt1=cnt2=tot=sum=sum1=sum2=0;
t1.clear(),t2.clear();
scanf("%d%d%d%d",&a,&b,&c,&d);
getchar(); cin>>s+1;
n=strlen(s+1);
if(a+b+(c+d<<1)!=n){ printf("NO\n"); continue; }
for(int i=1;i<=n;++i) if(s[i]=='A') ++cnt1; else ++cnt2;
if(cnt1!=a+c+d||cnt2!=b+c+d){ printf("NO\n"); continue; }
for(int i=2;i<=n;++i) if(s[i]==s[i-1]) qk[++tot]=i-1;
qk[++tot]=n;
for(int i=1;i<=tot;++i){
int t=qk[i]-qk[i-1]>>1;
if((qk[i]-qk[i-1])%2){
if(s[qk[i]]=='A') --a;
else --b;
sum+=t;
}else{
if(s[qk[i]]=='A') sum2+=t,t2.push_back(t);
else sum1+=t,t1.push_back(t);
}
}
if(a<0||b<0||a!=b){ printf("NO\n"); continue; }
sort(t1.begin(),t1.end()),sort(t2.begin(),t2.end());
for(int i=0;i<t1.size();++i){
if(c>=t1[i]) c-=t1[i];
else{
if(d+c+1>=t1[i]) d-=(t1[i]-c-1),--a,c=0;
else a-=(t1[i]-c-d),d=0,c=0;
}
if(a<0||c<0||d<0) break;
}
if(a<0||c<0||d<0){ printf("NO\n"); continue; }
for(int i=0;i<t2.size();++i){
if(d>=t2[i]) d-=t2[i];
else{
if(d+c+1>=t2[i]) c-=(t2[i]-d-1),--a,d=0;
else a-=(t2[i]-d-c),d=0,c=0;
}
if(a<0||c<0||d<0) break;
}
if(a<0||c<0||d<0){ printf("NO\n"); continue; }
if(a+c+d>=sum) printf("YES\n");
else printf("NO\n");
}
return 0;
}
[Codeforces Round #794 (Div. 2)] D. Linguistics的更多相关文章
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
- Codeforces Round #262 (Div. 2) 1003
Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...
- Codeforces Round #262 (Div. 2) 1004
Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...
- Codeforces Round #371 (Div. 1)
A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...
- Codeforces Round #268 (Div. 2) ABCD
CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...
- 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts
题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...
随机推荐
- 【React】学习笔记(二)——组件的生命周期、React脚手架使用
原教程视频:ttps://www.bilibili.com/video/BV1wy4y1D7JT?p=2&spm_id_from=pageDriver 目录 一.组件的生命周期 1.1.生命周 ...
- vuex和浏览器【sessionStorage,localStorage ..】 得区别
1.Vuex的主要作用是用来共享和管理数据,那为什么不直接使用浏览器缓存呢?2.Vuex和浏览器缓存策略的根本区别是什么?3.Vuex,state仓库中的数据流是单向同步的,那为什么可以在action ...
- DQL语句排序与分组
DQL语句排序与分组 一.DQL-排序 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列.分内部排序和外部排序,若整个 ...
- linux清理内存缓存cache
Linux服务器有自己先进的内存管理机制,有时候会发现我们系统的buff/cache内存占用会越来越高,操作系统也有卡顿的情况,遇到这种情况,不妨试试下面的方法. 1步骤一:我们先查看物理内存占用情况 ...
- k8s机器群扩容问题
今天遇到了一个很奇葩的问题.公司新人吧k8s集权扩容完后,发现服务器上的磁盘没有做分区2T磁盘没有做任何动作 把两台slave节点扩容上去的节点弄到了/目录.由于是生产环境情况比较特殊并没通过kube ...
- pip 国内源 包管理
配置国内源 linux配置 修改 ~/.pip/pip.conf 文件,如下,添加了源并修改了默认超时时间 [global] timeout = 3000 index-url = http://mir ...
- js中对小数的计算
在js 的计算中如果涉及到小数的运算,那结果可不要想当然了,比如 0.1+0.2 的计算 var num1 = 0.1; var num2 = 0.2; console.log(num1+num2) ...
- Python的几种lambda排序方法
1.对单个变量进行排序 #lst = [[5,8],[5,3],[3,1]] lst.sort(key = lambda x : x[1]) #lst = [[3,1],[5,8],[5,3]] 以元 ...
- 这次,听人大教授讲讲分布式数据库的多级一致性|TDSQL 关键技术突破
近年来,凭借高可扩展.高可用等技术特性,分布式数据库正在成为金融行业数字化转型的重要支撑.分布式数据库如何在不同的金融级应用场景下,在确保数据一致性的前提下,同时保障系统的高性能和高可扩展性,是分布式 ...
- OSError: dlopen() failed to load a library: cairo / cairo-2 / cairo-gobject-2 / cairo.so.2
解决办法 下载 gtk3-runtime-3.24.29-2021-04-29-ts-win64.exe后安装. 记得勾选添加bin目录到环境变量: 这样就不会缺失dll了,当然可能需要重启IDE才能 ...