扩展KMP( 一 )

Best Reward
题意:
将一段字符串 分割成两个串
如果分割后的串为回文串,则该串的价值为所有字符的权值之和(字符的权值可能为负数),否则为0。
问如何分割,使得两个串权值之和最大
题解:
将原串s1反转得到s2,然后进行s1,s2扩展KMP匹配,得到extend,对于s1的前i个字符如果和s2的后i个字符相等即extend[len-i] == i则前i个字符为回文串,同理,要判断后len-i个字符是否是回文串,对s2,s1进行扩展KMP即可

#include
#include
using namespace std;
const int MAXN=500010;
const int INF=0x7fffffff;
int nxt[MAXN],ex1[MAXN],ex2[MAXN];
char s1[MAXN],s2[MAXN];
int sum[MAXN],val[30];
void getNext(char *str,int *next)
{
    int i=0,j,p0,len=strlen(str);
    next[0]=len;
    while(i+1ans) ans=num;
        }
        printf("%d\n",ans);
    }
}

题意:
给一个数字字符串S, 可以把S最后一个数字移动到最前面变成另一个数字。例如123, 经过移动依次变成312,231,123。 注意当移动次数正好和S长度相等时,S又变回了最开始的那个数字。
求这个移动过程所形成的所有字符串,大于S(最初的)的数字,等于S,以及小于S的各有多少个。
题解:
因为比较数字大小主要是找第一个不同的的位的大小,所以我们可以利用扩展kmp。假设原串为s1,构造s2=s1+s1;然后s1作为模式串,对s1求next数组,s2求extend数组,那么extends[i]表示s2的第i个位置开始,与s1相同的字符的个数,所以要比较大小,只需比较s2[i+extend[i]]和s1[extend[i]]。需要注意的是,当extend[i]==strlen(s1),说明这两数字是相等的,还有就是,题目求的是不重复的数字的个数,所以还要借助循环节。

#include
#include
using namespace std;
const int MAXN=1e6;
char s1[MAXN],s2[MAXN];
int next[MAXN],extend[MAXN];
void getFail(char *str)
{
    int len=strlen(str);
    int j=0,k=-1;
    next[0]=-1;
    while(js1[extend[i]]) big++;
            else  les++;
        }
        printf("Case %d: %d %d %d\n",cas,les/num,equ/num,big/num);
    }
}

你可能感兴趣的:(扩展KMP( 一 ))