zoukankan      html  css  js  c++  java
  • AGC 036E

    相邻的相等串直接当成一个串。

    不妨设(Ale B,Ale C)

    考虑(A)选哪些已经确定的时候,如何调整(B)(C)

    把不用的(A)提出去之后再合并一下形成串(T)。不难发现(Ale B, Ale C)仍然成立。

    1. (B=C)的情况

    我们直接删除连续的(BC)串即可。

    容易证明一定能够做到。

    1. (B e C)的情况,不妨设(B<C)

    现在有(A+1​)个子串。定义( ext{unit string}​)为长度为(1​)并且左右都会(>1​)的子串。设(x,y​)分别为包含(B​)的串数量和(C​)( ext{unit string}​)数量。

    如果(x<y)(B)(C)的个数不可能相等。因为其他位置上(B-C)的数量最大是(1​)

    如果(xge y),那么是一定可以只删除(C)就直接做到(B= C)的。

    (b_1,b_2,c_1,c_2)分别表示(B/C ext{的string/unit string})个数。

    现在相当于要求(b_2le c_1)并且(c_2le b_1​)

    首先两个条件只会不满足一个。

    1. 删掉一个(A),四个值最多(-1)
    2. 如果删掉的(A)左边是一个(b_2)类型的串,(b_2)(-1)(c_1)不会变。那直接依次删掉即可。根据((1)),这样显然达到最优秀了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 4e6+5;
    int s[N],n;char tmple[N];
    int cnt[3];
    int p[3]={0,1,2};
     
    inline void _swap(int x,int y){
    	swap(p[x],p[y]);
    	for(int i=1;i<=n;i++){
    		if(s[i]==x)s[i]=y;
    		else if(s[i]==y)s[i]=x;
    	}
    }
     
    int b1,b2,c1,c2;
    vector<int> pc2;bool ban[N];
     
    void get(int l,int r){
    	if(l>r)return ;
    	int cntt[3]={0,0,0};
    	for(int i=l;i<=r;i++){
    		cntt[s[i]]++;
    	}
    	if(cntt[2]==0||cntt[1]==0){
    		if(cntt[2]&&l>1&&r<n)c2++,pc2.push_back(l-1);
    		if(cntt[1]&&l>1&&r<n)b2++;
    	}
    	if(cntt[2])c1++;
    	if(cntt[1])b1++;
    }
     
    void Sol(int l,int r){
    	if(l>r)return ;
    	if(l==r){
    		if(l==1||l==n){
    			if(s[l]==2&&cnt[2]>cnt[1])cnt[2]--,ban[l]=1;
    		}
    	}
    	if(l==r)return ;
    	if(s[l]==2&&cnt[2]>cnt[1])cnt[2]--,ban[l]=1;
    	if(s[r]==2&&cnt[2]>cnt[1])cnt[2]--,ban[r]=1;
    }
     
    int now,tar;
    void Sol2(int l,int r){
    	if(l>r)return ;
    	while(l<r&&now>tar){
    		if(l+1>=r && l!=1 && r!=n)break;
    		now--;ban[l]=ban[l+1]=1;l+=2;
    	}
    }
     
    int main()
    {
    	scanf("%s",tmple+1);int lll=strlen(tmple+1);
    	for(int i=1;i<=lll;i++)if(i==1||tmple[i]!=tmple[i-1])s[++n]=tmple[i]-'A';
    	for(int i=1;i<=n;i++)cnt[s[i]]++;
    	for(int i=0;i<3;i++)for(int j=i+1;j<3;j++)if(i!=j){
    		if(cnt[i]>cnt[j]){
    			_swap(i,j);
    			swap(cnt[i],cnt[j]);
    		}
    	}
    	int lst=0;
    	for(int i=1;i<=n;i++)
    		if(s[i]==0){get(lst+1,i-1);lst=i;}
    	get(lst+1,n);
    	if(b1<c2){
    		int ct=c2-b1;
    		for(int i=0;i<ct;i++){
    			ban[pc2[i]]=1,cnt[0]--;
    		}
    	}
    	lst=-1;int nn=0;
    	for(int i=1;i<=n;i++)if(!ban[i]){
    		if(lst!=s[i])lst=s[i], s[++nn]=s[i];
    	}n=nn;
    	cnt[0]=cnt[1]=cnt[2]=0;
    	for(int i=1;i<=n;i++)cnt[s[i]]++;
    	memset(ban,0,sizeof(ban));
    	lst=0;
    	for(int i=1;i<=n;i++)
    		if(s[i]==0){Sol(lst+1,i-1);lst=i;}
    	Sol(lst+1,n);
    	lst=-1,nn=0;
    	for(int i=1;i<=n;i++)if(!ban[i]){
    		if(lst!=s[i])lst=s[i], s[++nn]=s[i];
    	}n=nn;
    	cnt[0]=cnt[1]=cnt[2]=0;
    	for(int i=1;i<=n;i++)cnt[s[i]]++;
    	memset(ban,0,sizeof(ban));
    	now=cnt[1],tar=cnt[0];
    	lst=0;
    	for(int i=1;i<=n;i++)
    		if(s[i]==0){Sol2(lst+1,i-1);lst=i;}
    	Sol2(lst+1,n);
    	for(int i=1;i<=n;i++){
    		if(!ban[i])printf("%c",'A'+p[s[i]]);
    	}
    }
    
  • 相关阅读:
    python学习笔记(五)
    python学习笔记(四)
    Jenkins学习系列——iOS打包任务的创建和配置
    Jenkins学习系列——jenkins平台搭建和配置
    java及java web学习笔记
    mac book下批量替换多个文件中的字符
    MAC的sed和GNU不一样
    python杂记
    appium ios环境搭建——iOS开发环境搭建
    ideviceinstaller报Segmentation fault: 11错误解决过程
  • 原文地址:https://www.cnblogs.com/weiyanpeng/p/11407993.html
Copyright © 2011-2022 走看看