Codeforces Round #545 (Div. 2)D(KMP,最长公共前后缀,贪心)

#include<bits/stdc++.h>
using namespace std;
const int N=1000007;
char s1[N],s2[N];
int len1,len2;
int nex[N];
int cnt1[7],cnt2[7];
int main(){
    scanf("%s %s",s1+1,s2+1);
    len1=strlen(s1+1);
    len2=strlen(s2+1);
    for(int i=1;i<=len1;i++)
        cnt1[s1[i]-‘0‘]++;
    for(int i=1;i<=len2;i++)
        cnt2[s2[i]-‘0‘]++;
    if(cnt1[1]>=cnt2[1]&&cnt1[0]>=cnt2[0]){//如果个数足够先输出s2
     for(int i=1;i<=len2;i++)
            putchar(s2[i]);
     cnt1[0]-=cnt2[0];
     cnt1[1]-=cnt2[1];
    }
    for(int i=2,j=0;i<=len2;i++){//kmp寻找最长公共前后缀
        while(s2[i]!=s2[j+1]&&j)//这一位不相等就把模式串返回到标记
            j=nex[j];
        if(s2[i]==s2[j+1])//相等就让模式串位置前进,模式串可能为空此时不需要使模式串标记前进,因为模式串里面没有能和主串相等的字符
            j++;
        nex[i]=j;//记录标记,以便以后返回
    }
    while(cnt1[1]&&cnt1[0]){
     int flag=0;
     for(int i=nex[len2]+1;i<=len2;i++){//贪心地从最长公共前后缀的下一位开始输出
      if(cnt1[s2[i]-‘0‘]){
       putchar(s2[i]);
       cnt1[s2[i]-‘0‘]--;
      }
      else{
       flag=1;
                break;
      }
     }
     if(flag)
            break;
    }
    for(int i=1;i<=cnt1[0];i++)//输出剩余的0或1
        putchar(‘0‘);
    for(int i=1;i<=cnt1[1];i++)//输出剩余的0或1
        putchar(‘1‘);
}

原文地址:https://www.cnblogs.com/ldudxy/p/10508226.html

时间: 2024-11-06 23:18:52

Codeforces Round #545 (Div. 2)D(KMP,最长公共前后缀,贪心)的相关文章

Codeforces Round #606 (Div. 2) D. Let&#39;s Play the Words?(贪心+map)

?? ?? ?? 题意:给你一些序列,要求把这些序列翻转之后能首尾相连(01,10),并且字符串不能相同,询问最小步数: 1.我们只关心这个字符串首尾位置,一共只有四种情况:00,01,10,11:00 和 11 是没必要翻转的,剩下 01,10 只要存在就可以相互抵消(0110,1001这种),剩下多的 01 or 10,就是我们最后需要翻转的字符串,数量为abs(num01-num10)/2: 2.为了满足字符串不能相同,一开始就记录下哪写字符串不可以翻转,例,假如s翻转之后为rev,rev

【kmp+求所有公共前后缀长度】poj 2752 Seek the Name, Seek the Fame

http://poj.org/problem?id=2752 [题意] 给定一个字符串,求这个字符串的所有公共前后缀的长度,按从小到达输出 [思路] 利用kmp的next数组,最后加上这个字符串本身 [AC] 1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<cstdio> 5 #include<algorithm> 6 using namespace s

Codeforces Round #545 Div. 1自闭记

A:求出该行该列各有多少个比其小的取max,该行该列各有多少个比其大的取max,加起来即可. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 1010 char ge

Codeforces Round #545 (Div. 2) 掉分记

每次CF后,我的rating下降,掉分让我悲痛欲绝 ——题记 ### 前言 这次 CF 时间可谓是极好的,17:05 开始,时长 2h 30min. 4:40 回到家,开电脑. 在看了一会书后,比赛开始了. ### 正文 首先,第一个掉分的 flag 出现了! 卡,卡,卡! CF 又双叒叕卡了! 1分钟过去了…… 2分钟过去了…… 3分钟过去了…… Dashboard 一直打不开.. 当时间已经接近 17:10 分的时候,我终于打开了 A 题.. 然而,这还并不是我掉分的所有原因. 先迅速浏览了

Codeforces Round #545 (Div. 2) D

链接:http://codeforces.com/contest/1138/problem/D 啊啊啊啊啊啊,自闭啊,比赛的时候判断条件 if(s1[i-1]=='0') aa++;写成了 if(s1[i]=='0') aa++;少写了个-1,被hack了,上分场变成了掉分场. 思路; 题目需要t字符串出现次数最多,那么找到最大的重叠部分就好了,然后依次加上就好了 主要就是要找到字符串t与本身的重叠部分,,假设有两个t,第一个t不变,第二个t向右移动: 比如: 10101010 -1010101

Codeforces Round #545 (Div. 2)A. Sushi for Two

全世界最笨的人 出现了 这题真的好欺骗我的感情,表面上先给我过了,让我快乐一下,背地里再把我给踢掉 TUT干嘛这么坏啊!!!!!!!!!!!!! 好吧,其实这个错误昨天晚上就反过了 但是世界上最笨的女同学她是不会改的 如果你下次还不改 那你还是世界上最笨的女同学 如果你改了 那你...... TUT... 我们来分析一下,为什么这个女同学,连A题都过不了 这题的题意很简单,就是要求长得像AAABBB的序列的最大值 我先选了一种很弱智的方法 就是,先求前面那个连续序列的长度,再求后面那个连续序列的

Codeforces Round #545 (div 1.)

B.Camp Schedule 给两个 $01$ 串 $s$ 和 $t$,你可以将 $s$ 串任意重排,要求最大化 $t$ 在 $s$ 子串中出现的次数,可以重叠 $|s|,|t| \leq 500000$ sol: 看到可以重叠,考虑最大化利用重叠部分 重叠部分是这次 $t$ 串的结束和下次 $t$ 串的开始,也就是 $t$ 串的一个 $border$ 先放一个 $border$ ,之后一直放 $t$ 串的除 $border$ 以外的部分就可以了 #include <bits/stdc++.h

Codeforces Round #422 (Div. 2) C. Hacker, pack your bags! 排序,贪心

C. Hacker, pack your bags! It's well known that the best way to distract from something is to do one's favourite thing. Job is such a thing for Leha. So the hacker began to work hard in order to get rid of boredom. It means that Leha began to hack co

Codeforces Round #407 (Div. 2)(争取明天24点前补掉)

A - Anastasia and pebbles(水题) 题意: 一个人有俩口袋,每个口袋最多装k个,然后每天每个口袋里的石头颜色必须都相同,问你最少用几天能装完. 思路: 水题..一不小心写瓷了,以为A题大水题,瞎写也不会T,没仔细想..写了一个T的代码. 1 #include <bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int n, k; 6 cin >> n >> k; 7 vector&l