码迷,mamicode.com
首页 > 其他好文 > 详细

CF1137B Camp Schedule

时间:2020-03-13 20:30:23      阅读:60      评论:0      收藏:0      [点我收藏+]

标签:can   sed   next数组   图片   onclick   16px   span   %s   技术   

CF1137B Camp Schedule

题意:s和t均由0和1构成。要求重组s串,使得t在s中出现的次数最多。

思路:
统计s中0和1的个数,基于t串构造新的s串。
设j是t的指针,从t串的首位开始依次向后:
如果t[j]对应的数字仍有剩余,输出t[j],否则退出循环,输出剩下的数字。
如果j已经到达t串的末尾,j退回到s[j]对应最长前缀的后一位。(相当于合并相同的前后缀)。因此,要求出t串的最长公共前后缀 Next数组。
如:s:1111110000 t:110011 ,当j到达t串末尾时,此时输出为110011;第一个t串的后缀11形成了后一个t串的前缀11。因此构成的新s串为:1100110011
 
AC代码:
技术图片
#include <iostream>
#include <cstring>
using namespace std;
const int N=500000+10;
int Next[N];
char s[N],t[N];

void GET_next(char* t, int Next[])
{
    int j = 0;
    int len=strlen(t+1);
    for(int i = 2; i <= len; i++){
        while(j && t[j+1] != t[i]){
            j = Next[j];
        }
        if(t[j+1] == t[i]) j++;
        Next[i] = j;
    }
}

int main()
{
    scanf("%s",s+1);
    scanf("%s",t+1);
    int l1=strlen(s+1);
    int l2=strlen(t+1);
    int s0=0,s1=0;
    
    for (int i=1;i<=l1;i++){
        if (s[i]==0) s0++;
        else s1++;
    }
    GET_next(t,Next);
    int j=1;
    for (int i=1;i<=l1;i++){
        if (t[j]==0){
            if (s0) {
                cout<<0;s0--;
            }
            else break;
        }
        else{
            if (s1) {
                cout<<1;s1--;
            }
            else break;
        }
        j++;
        if (j==l2+1) j=Next[l2]+1;
    }
    if (s0) for (int i=1;i<=s0;i++) cout<<0;
    if (s1) for (int i=1;i<=s1;i++) cout<<1;
    return 0;
}
View Code

 

CF1137B Camp Schedule

标签:can   sed   next数组   图片   onclick   16px   span   %s   技术   

原文地址:https://www.cnblogs.com/chillilly/p/12488523.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!