一开始就想到了扩展KMP,因为只有扩展KMP才是处理后缀的。但忽然短路以为扩展KMP求的是最长公共后缀,囧。。。。又浪费了很多时间,都是对这个算法练得不多

再看那个扩展KMP算法之后,就很确定要的就是这个算法了。嗯,如果直接用扩展KMP,是会超时的。后来看了别人一个很巧妙的处理,把一个串复制一下两个串拼起来,再求扩展KMP。天才的做法啊。。。

还需要考虑一个问题,就是判重。这个真心不懂,总觉得和循环有点关系,但却想不到什么好方法。好吧,其实这个算法我也懂的,但很久没用过了,用KMP求循环节。当这个串是循环的,就代表有重复了。。。

#include <iostream>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <cstdio> using namespace std; char str1[200010],str2[100010];
int next[100010],extand[200010];
int knext[100010]; void getnext(char *T){// next[i]: 以第i位置开始的子串 与 T的公共前缀
int i,length = strlen(T);
next[0] = length;
for(i = 0;i<length-1 && T[i]==T[i+1]; i++);
next[1] = i;
int a = 1;
for(int k = 2; k < length; k++){
int p = a+next[a]-1, L = next[k-a];
if( (k-1)+L >= p ){
int j = (p-k+1)>0? (p-k+1) : 0;
while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较
next[k] = j, a = k;
}
else next[k] = L;
}
}
void getextand(char *S,char *T){
memset(next,0,sizeof(next));
getnext(T);
int Slen = strlen(S), Tlen = strlen(T), a = 0;
int MinLen = Slen>Tlen?Tlen:Slen;
while(a<MinLen && S[a]==T[a]) a++;
extand[0] = a, a = 0;
for(int k = 1; k < Slen; k++){
int p = a+extand[a]-1, L = next[k-a];
if( (k-1)+L >= p ){
int j = (p-k+1)>0? (p-k+1) : 0;
while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++;
extand[k] = j;a = k;
}
else extand[k] = L;
}
} void Getnxt(char *S){
knext[0]=-1;
int i=1,j=0;
int len=strlen(S);
while(i<len){
if(S[i]==S[j]||j==-1){
i++;
j++;
knext[i]=j;
}else{
j=knext[j];
}
}
} int main(){
int T,le,equ,ga;
scanf("%d",&T);
int kase=0;
while(T--){
cin>>str2;
memcpy(str1,str2,sizeof(str2));
strcat(str1,str2);
getextand(str1,str2);
le=equ=ga=0;
int len=strlen(str2);
for(int i=len-1;i>=0;i--){
if(extand[i]>=len)
equ++;
else{
if(str1[i+extand[i]]<str2[extand[i]])
le++;
else ga++;
}
}
Getnxt(str2);
int qt=1;
len=strlen(str2);
int t=len-knext[len];
if(len%t==0){
qt=len/t;
}
printf("Case %d: %d %d %d\n",++kase,le/qt,equ/qt,ga/qt);
}
return 0;
}

  

最新文章

  1. 关于SubSonic3.0生成的表名自动加复数(s)的“用户代码未处理SqlException,对象名&#39;xxxs&#39;无效”异常处理
  2. 台球游戏的核心算法和AI(2)
  3. 在使用sqlite时淌过的坑
  4. JS之apply,call,bind区别
  5. myEclipse中新建的项目导入到Eclipse之后项目出现一个红色的叉叉
  6. Bluebird-Core API(二)
  7. Objective-C ,ios,iphone开发基础:ios数据库(The SQLite Database),使用终端进行简单的数据库操作
  8. Android - Layout时发生&#39;Unfortunately xxx has stopped&#39;
  9. 上拉、下拉UITableView,交互式 模态弹出(自定义弹出动画)
  10. java中八大基本数据类型详解
  11. JS 引入方式 基本数据类型 运算符 控制语句 循环 异常
  12. MySQL架构备份之双机热备
  13. Linux-基础学习(六)-Redis的进阶学习
  14. ORACLE用户表空间使用情况查询
  15. C# 两个datatable中的数据快速比较返回交集或差集[z]
  16. html 设置input框的记忆功能(联想内容)
  17. st-link调试和下载程序(待写)
  18. SVN多分支开发模式V1.0.1
  19. activemq 消息类型
  20. BZOJ.3329.Xorequ(数位DP)

热门文章

  1. tomcat设置编码utf8
  2. Blade - 腾讯开源的构建系统 c/c++编译环境
  3. An internal error occurred during: &amp;quot;Building workspace&amp;quot;. java.lang.StackOverflowError
  4. apple Swift语言新手教程
  5. Android应用之——自己定义控件ToggleButton
  6. 希尔加密算法(湖南师范大学第六届大学生计算机程序设计竞赛)hnuoj11552
  7. $scope angular在controller之外调用
  8. ASP.NET Core-组件:目录
  9. Vmware 安装samba
  10. 12. Integer to Roman[M]整数转罗马数字