CF1809D Binary String Sorting 题解

CF1809D Binary String Sorting

贪心。由于每次操作的代价都很大,所以需要优先减少操作次数,然后尽量多使用交换操作。

易得交换操作最多只会发生一次,因为每次交换操作只能消除一个逆序对,当存在两个或多个逆序对时,可以通过删除操作来减少更多的逆序对,减少操作次数。当只存在一个逆序对时,自然也只能交换一次。

然后,由于排序结束后 01 之间必然有一条分界线,左边是 0,右边是 1。我们考虑枚举这条分界线,在分界线左边的 1 需要删除,在分界线右边的 0 需要删除。在分界线的同侧进行交换操作是无意义的,因为这并不会减少左边的 1 或右边的 0

如果一次交换操作能恰好把左边的 1 换到右边,右边的 0 换到左边,那么可以优先执行这个交换操作,我们发现这种情况只会在分界线左右第一个元素发生,正好印证了上文交换操作最多只会发生一次。所以,当分界线左边第一个元素为 1,右边第 1 个元素为 0 时,需要进行一次交换操作,从而减少两次修改操作。

如果分界线不满足左边第一个元素为 1,右边第 1 个元素为 0 时,其实也不用处理分界线左右第一个元素。因为无论是 00 还是 11 还是 01,其实都是符合条件的数对,并不会影响结果。

#include <bits/stdc++.h>
using namespace std;
long long t,n,sf=1e12,df=1e12+1;
char str[400000];
int main()
{
	scanf("%lld",&t);
	while(t--)
	   {
	   	long long s0=0,s1=0,z=0,y=0,ans=1e18;
	   	scanf("%s",str+1);
	   	n=strlen(str+1);
	   	for(int i=2;i<=n;i++)
	   	    if(str[i]=='0')y++;
	   	for(int i=1;i<=n-1;i++)
	   	    {
	   	    if(str[i+1]=='0')y--;
			if(str[i-1]=='1')z++;	
	   	    if(str[i]=='1'&&str[i+1]=='0')ans=min(ans,(z+y)*df+sf);
	   	    else ans=min(ans,(z+y)*df);
		    }
		if(ans==1e18)printf("0\n");
		else printf("%lld\n",ans);
	   }
	return 0;
}

AC记录

posted @   w9095  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示