zoukankan      html  css  js  c++  java
  • CF1458D Flip and Reverse

    一、题目

    点此看题

    二、解法

    没有什么好的想法,就从图论的角度入手吧。

    要根据题目特性来建图,首先要考虑把什么当做点的问题,如果把字符串的元素当成点是不好表示 子串必须包含同样数量的字符0与1 这个限制的。但是前缀和可以方便地表示这个限制,令 (1)(1)(0)(-1),那么如果 (sum_l=sum_r) 就说明这是一个可以操作的区间,那么我们把前缀和建成点

    还要考虑怎么表示字符串里的元素,直接当成边建上去,对于元素 (s_i),将点 (sum_{i-1})(sum_i) 连一条标记为 (s_i) 的边,考虑原始字符串就对应了这张图里的某一条欧拉回路(因为要把所有的边访问完)

    那么把转换和翻转操作对应到图上,因为有边相连的两个点编号相差 (1),所以这张图是很特别的。首先选出一条起点终点相同的路径,然后把沿路经过的边换方向即可,你会发现新的路径正好对应操作之后的字符串。

    现在的问题是最小化字典序,有一个结论:所有欧拉路径都对应着操作后的合法字符串。考虑走到 (x) 之后出现了两种存在欧拉路径的选择 (x-1)(x+1),因为都是欧拉路径所以往一边走一定能走回来,那么说明存在边 x-1->xx+1->x,如果应该走 x+1(即是对应原字符串的走法)那么是 x->x+1->x->x-1->x,可以通过操作换成 x->x-1->x->x+1->x,这正好对应走 x-1 的方法,虽然它并不对应原字符串但是合法的。

    那么找到原图定起点定终点,经过标记字典序最小的欧拉回路即可,根据图的特性可以设计如下贪心。

    • 如果 x-1 走过去并且能走回来,那么无脑走 x-1 即可。
    • 否则 x-1 走过去就回不来了,那么走 x+1;如果走不了 x+1 是可以直接走 x-1 的。

    代码非常好写,时间复杂度 (O(n))

    三、总结

    套路:差分,前缀和。差分可以在区间打标记修改之类的问题使用,前缀和在有区间权值限制的问题使用。

    如果要用图论,思考每类元素的意义(是建成边还是建成点),学会把限制建在图上是很重要的。

    #include <cstdio>
    #include <cstring>
    const int M = 500005;
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int T,n,a[2*M][2];char s[M];
    void work()
    {
        scanf("%s",s+1),n=strlen(s+1);
        int x=n;
        for(int i=1;i<=n;i++)
        {
            a[x][s[i]-'0']++;
            if(s[i]=='0') x--;
            else x++;
        }
        x=n;
        for(int i=1;i<=n;i++)
        {
            if(a[x][0] && a[x-1][1]) a[x][0]--,x--,printf("0");
            else if(a[x][1]) a[x][1]--,x++,printf("1");
            else a[x][0]--,x--,printf("0");
        }
        puts("");
    }
    signed main()
    {
        T=read();
        while(T--) work();
    }
    
    
  • 相关阅读:
    面试题:JS中map的陷阱
    C#中正则表达式进行忽略大小写的字符串替换
    C#窗体钉在桌面、置底、嵌入桌面的办法
    创建C#串口通信程序详解
    为类和函数代码自动添加版权注释信息
    C# 如何编辑文件的摘要信息
    C# GDI在控件上绘图
    泛型Dictionary的用法详解
    Winform 导出成Excel打印代码
    C#反射深入学习
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/14967601.html
Copyright © 2011-2022 走看看