zoukankan      html  css  js  c++  java
  • Codeforces Round #545 (Div. 2)-Camp Schedule

        题目要求,给定一个s序列,一个p序列,问能不能对s做相应的调整,使得s序列中,有尽可能多的p子串(可以重复)

        最开始我拿到这个题目,也是一点头绪都没有,如何做调整呢?

        首先考虑如何会有尽可能多的子串,可以相交那种?

        貌似我们要找的就是子串后缀和前缀匹配度

       这里再次补充一下KMP中next数组的意义

       首先要理解next数组的含义:https://www.cnblogs.com/chenxiwenruo/p/3546457.html

       那么我们通过求next数组,很容易知道知道,t的最小循环长度是k=len_t-next[len_t]

       但是最小循环长度是k,我们需要尽量多的构造这个最小循环,并且放在一起,余下的尽量按照最小循环进行往后匹配

       当时补题的时候,我自己在想,我们已经把尽量多的最小循环个数的构造出来了,余下的是不是不用再安装最小循环进行

       匹配呢?事实上是不行的,我们知道最小循环的意思是,把原本长度数组,可以用它的某个前缀进行循环表示。所以构造的字符,最后k个仍然只是前缀,如果匹配完的1,0仍然剩余,我们需要把1,0安装原来序列继续匹配,如果数量够的话,是会增加子串个数的。。。

       

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    using namespace std;
    const int maxx = 500000+5;
    char s[maxx];
    char t[maxx];
    int net[maxx];
    int len_s;
    int len_t;
    void get_next()
    {
        net[1]=0;
        for (int i=2,j=0; i<=len_t; i++)
        {
            while(j>0 && t[i]!=t[j+1])j=net[j];
            if(t[i]==t[j+1])j++;
            net[i]=j;
        }
    }
    int main()
    {
        int n,cnt_s,k,p,a,b,time;
        while(~scanf("%s",1+s))
        {
            scanf("%s",1+t);
            len_s=strlen(s+1);
            len_t=strlen(t+1);
            a=0;
            for (int i=1; i<=len_s; i++)
            {
                a+=s[i]-'0';
            }
            b=len_s-a;
            len_t=strlen(t+1);
            get_next();
            k=len_t-net[len_t];//最小循环节长度
            cout<<k<<endl;
            p=0;
            for (int i=1; i<=k; i++)
            {
                p+=t[i]-'0';
            }
            if(p==0)
            {
                time=b;
            }else if (p==k){
                time=a;
            }
            else
            {
                time=min(a/p,b/(k-p));
            }
            for (int i=1;i<=time;i++){
                for (int j=1;j<=k;j++){
                    printf("%c",t[j]);
                }
            }
            a-=time*p,b-=time*(k-p);
            int g=1;
            while(a||b){
                if(b){
                    printf("0");
                    b--;
                }
                if(a){
                    printf("1");
                    a--;
                }
            }
            printf("
    ");
        }
        return 0;
    }
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    4Sum
    3Sum Closest
    3Sum
    Longest Common Prefix
    Roman to Integer
    thinkphp3.2自定义配置文件
    centos7下git的使用和配置
    git 报错
    Git服务器安装详解及安装遇到问题解决方案
    centos GIT安装
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10610531.html
Copyright © 2011-2022 走看看