Minimum Integer sequence HDU - 3522(扩展KMP)

Minimum Integer sequence

HDU - 3522

题意:

几行代码看了一个多小时!!吐血!!

明天再来补题~

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=100010;
 4 char s[maxn],t[maxn];
 5 int lens,lent;
 6 int nex[maxn],ex[maxn];
 7 int best;
 8
 9 void getnex(char* t){
10     nex[0]=lent;
11     int a=0,p=0;
12     for(int i=1;i<lent;i++){
13         if(i>=p||i+nex[i-a]>=p){
14             if(i>=p) p=i;
15             while(p<lent&&t[p]==t[p-i]) p++;
16             nex[i]=p-i;
17             a=i;
18         }else nex[i]=nex[i-a];
19     }
20 }
21 void exkmp(char* s,char* t){
22     getnex(t);
23     int a=0,p=0;
24     for(int i=0;i<lens;i++){
25         if(i>=p||i+nex[i-a]>=p){
26             if(i>=p) p=i;
27             while(p<lens&&p-i<lent&&s[p]==t[p-i]) p++;
28             ex[i]=p-i;
29             a=i;
30         }else ex[i]=nex[i-a];
31     }
32 }
33 bool smaller(int x,int j){
34     if(ex[j]+j<x) return s[j+ex[j]]<t[ex[j]];
35     if(nex[x-j]+x-j<lent) return t[nex[x-j]]<t[x-j+nex[x-j]];
36     if(nex[lent-(x-j)]<x-j) return t[lent-(x-j)+nex[lent-(x-j)]]<t[nex[lent-(x-j)]];
37     return 0;
38 }
39 int main(){
40     while(scanf("%s%s",s,t)!=EOF){
41         lens=strlen(s);lent=strlen(t);
42         exkmp(s,t);
43         best=0;
44         for(int i=0;i<lens;i++){
45             if(smaller(i+1,best)) best=i+1;
46         }
47         for(int i=0;i<best;i++) putchar(s[i]);
48         printf("%s",t);
49         printf("%s\n",s+best);
50     }
51     return 0;
52 }

终于a掉了500题!!!

留念!!

时间: 2024-10-10 01:51:28

Minimum Integer sequence HDU - 3522(扩展KMP)的相关文章

hdu 4333 扩展kmp+kmp重复字串去重

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333 关于kmp next数组求最短重复字串问题请看:http://www.cnblogs.com/z1141000271/p/7406198.html 扩展kmp请看:http://www.cnblogs.com/z1141000271/p/7404717.html 题目大意:一个数字,依次将第一位放到最后一位,问小于本身的数的个数及等于本身的个数和大于本身的个数,但是要注意重复的不再计算 题解:

HDU 3336 扩展kmp

题目大意: 找到字符串中所有和前缀字符串相同的子串的个数 对于这种前缀的问题,通常通过扩展kmp来解决 其实吧这是我第一次做扩展kmp的题目,原来确实看过这个概念,今天突然做到,所以这个扩展kmp的模板是做到这道题直接copy的 这里用扩展kmp很好解决问题,_next[i],表示第i位开始所能匹配到的最大公共前缀长度,比如说这个长度为4,那么说明前缀1,2,3,4都出现了一次,我们只在cnt[4]++ 那么最后从n到1,逆向更新cnt[i] += cnt[i+1]即可,最后得到cnt[i]就表

HDU 4333 扩展KMP

点击打开链接 题意:一个数字,依次将第一位放到最后一位,问小于本身的数的个数及等于本身的个数和大于本身的个数,但是要注意重复的不再计算 思路:用扩展KMP我们可以处理,先将串复制到后面一次,然后求扩展KMP,那么我们如何比较呢,如果extand[i]的值大于串的长度len,说明我以i为开头的串和原串的匹配大于len,也就说明这个串和原串相等,接下来就是另外两种情况,若extand[i]匹配到了第三位,那么久比较原串的第三位和以i开始的第三位即可,比较过后,处理重复的串,用KMP即可处理,如果串是

Number Sequence - HDU 1711(KMP模板题)

题意:给你一个a串和一个b串,问b串是否是a串的子串,如果是返回b在a中最早出现的位置,否则输出-1 分析:应该是最简单的模板题了吧..... 代码如下: ============================================================================================== #include<stdio.h> #include<string.h> const int MAXM = 1e4+7; const int

HDU 2594 扩展kmp模板题

题目大意: 给定两个字符串,在第一个字符串中找到一个最大前缀作为第二个字符串的后缀 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <climits> 8 #include <cmath>

hdu 3613 扩展kmp+回文串

题目大意:给个字符串S,要把S分成两段T1,T2,每个字母都有一个对应的价值,如果T1,T2是回文串(从左往右或者从右往左读,都一样),那么他们就会有一个价值,这个价值是这个串的所有字母价值之和,如果不是回文串,那么这串价值就为0.问最多能获得多少价值?   对于我们只需要枚举扫描一遍extend数组,扫描到的当前位置之前为前半部分T1, 然后用根据extend数组可以判断T1是否是回文.那后半部分T2呢?  刚才是用S去匹配T, 如果要求后缀,只需要用T去匹配S,再得到一个数组extend2即

hdu 3613 扩展KMP运用

题意是给你一个串    只包含a-z   每个字母对应一个价值    问把他进行一次分割成两段     若其中一段是会问串  子价值为之和否则为零     问最大的价值: 先把串str1进行反转 为str2       判断s1的前i个是不是回文串   对str2(文本串)  str1(模式串)进行EKMP   只要i==extand1[len-i] 则是回文   若要判断后i个是不是回文串 则反过来把str1作文本串  str2作模式串   进行EKMP   就ok了 #include<std

HDU 6153 A Secret(扩展KMP模板题)

A Secret Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others) Total Submission(s): 2523    Accepted Submission(s): 934 Problem Description Today is the birthday of SF,so VS gives two strings S1,S2 to SF as a present,w

扩展KMP,附上例题(HDU - 4333 Revolving Digits)

给出模板串S和串T,长度分别为Slen和Tlen,在线性时间内,对于每个S[i](0<=i<Slen),求出S[i..Slen-1]与T的 最长公共前缀长度,记为extend[i],extend[i]存放s[i]开始与T的最长公共前缀长度. 例子 a a a a a a a b b b a a a a a c extend 5 4 3 2 1 0 0 0 0 0 HDU - 4333 Revolving Digits Time Limit: 3000/1000 MS (Java/Others)