CF1809D Binary String Sorting 题解
贪心。由于每次操作的代价都很大,所以需要优先减少操作次数,然后尽量多使用交换操作。
易得交换操作最多只会发生一次,因为每次交换操作只能消除一个逆序对,当存在两个或多个逆序对时,可以通过删除操作来减少更多的逆序对,减少操作次数。当只存在一个逆序对时,自然也只能交换一次。
然后,由于排序结束后 和 之间必然有一条分界线,左边是 ,右边是 。我们考虑枚举这条分界线,在分界线左边的 需要删除,在分界线右边的 需要删除。在分界线的同侧进行交换操作是无意义的,因为这并不会减少左边的 或右边的 。
如果一次交换操作能恰好把左边的 换到右边,右边的 换到左边,那么可以优先执行这个交换操作,我们发现这种情况只会在分界线左右第一个元素发生,正好印证了上文交换操作最多只会发生一次。所以,当分界线左边第一个元素为 ,右边第 个元素为 时,需要进行一次交换操作,从而减少两次修改操作。
如果分界线不满足左边第一个元素为 ,右边第 个元素为 时,其实也不用处理分界线左右第一个元素。因为无论是 还是 还是 ,其实都是符合条件的数对,并不会影响结果。
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探