hdu 4333(扩展kmp)
题意:就是给你一个数字,然后把最后一个数字放到最前面去,经过几次变换后又回到原数字,问在这些数字中,比原数字小的,相等的,大的分别有多少个。比如341-->134-->413-->341,所以和原数字相比,比原数字小的有一个,相等的有一个,大的有一个。
分析:经过观察,其实就是求每一位的后缀与自身的最长公共前缀,这个显然可以用扩展kmp处理,但是开始的时候我超时了,后来在网上看到别人把这个串后面再接上本身,以它为主串,然后以自身为模板串进行扩展kmp,这样处理把时间复杂度降到了线性的,最后要注意的一个问题就是如何避免重复了,我们可以用普通的kmp求出此串的最小循环节,如果构成完整的循环,那么我们要算的就是循环节长度的情况了!
代码实现:
#include<stdio.h>
#include<string.h>
char S[],T[];
int next[],extend[],len,node; void get_node()
{
int i=,j=-;
next[]=-;
while(i<len)
{
if(j==-||T[i]==T[j])
{
i++;j++;
next[i]=j;
}
else
j=next[j];
}
node=len-next[len];
} void get_next()
{
int a,p,k,j,len;
int L;
len=strlen(T);
next[]=len;
a=;
while(a<len-&&T[a]==T[a+])
a++;
next[]=a;
a=;
for(k=;k<len;k++)
{
p=a+next[a]-;
L=next[k-a];
if(k-+L>=p)
{
j=p-k+>?p-k+:;
while(j+k<len&&T[j+k]==T[j])
j++;
next[k]=j;
a=k;
}
else
next[k]=L;
}
} void get_extend()
{
get_next();
int a,p,L,k,j,slen,tlen,len;
slen=strlen(S);tlen=strlen(T);
len=slen>tlen?tlen:slen;
a=;
while(a<len&&S[a]==T[a])
a++;
extend[]=a;
a=;
for(k=;k<slen;k++)
{
p=a+extend[a]-;
L=next[k-a];
if(k-+L>=p)
{
j=p-k+>?p-k+:;
while(j+k<slen&&j<tlen&&S[j+k]==T[j])
j++;
extend[k]=j;
a=k;
}
else
extend[k]=L;
}
} void solve()
{
int i,num1=,num2=,num3=,flag;
if(len%node!=)
node=len;
for(i=;i<node;i++)
{
if(extend[i]>=len)
num2++;
else if(S[extend[i]]>S[i+extend[i]])
num1++;
else if(S[extend[i]]<S[i+extend[i]])
num3++;
}
printf("%d %d %d\n",num1,num2,num3);
} int main()
{
int t,i;
scanf("%d",&t);
getchar();
for(i=;i<=t;i++)
{
scanf("%s",T);
strcpy(S,T);
strcat(S,T);
len=strlen(T);
get_node();
get_next();
get_extend();
printf("Case %d: ",i);
solve();
}
return ;
}
hdu 4333(扩展kmp)的更多相关文章
- hdu 4333 扩展kmp+kmp重复字串去重
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333 关于kmp next数组求最短重复字串问题请看:http://www.cnblogs.com/z ...
- HDU 3336 扩展kmp
题目大意: 找到字符串中所有和前缀字符串相同的子串的个数 对于这种前缀的问题,通常通过扩展kmp来解决 其实吧这是我第一次做扩展kmp的题目,原来确实看过这个概念,今天突然做到,所以这个扩展kmp的模 ...
- HDU 6153 扩展kmp
A Secret Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others)Total ...
- HDU 3613 扩展KMP
暴力枚举大水题,判断回文,扩展KMP #include <cstdio> #include <cstring> #include <algorithm> using ...
- HDU 2594 扩展kmp模板题
题目大意: 给定两个字符串,在第一个字符串中找到一个最大前缀作为第二个字符串的后缀 #include <iostream> #include <cstdio> #include ...
- hdu 3613 扩展kmp+回文串
题目大意:给个字符串S,要把S分成两段T1,T2,每个字母都有一个对应的价值,如果T1,T2是回文串(从左往右或者从右往左读,都一样),那么他们就会有一个价值,这个价值是这个串的所有字母价值之和,如果 ...
- HDU 6153 A Secret(扩展KMP模板题)
A Secret Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others) Total ...
- HDU 4333 Revolving Digits 扩展KMP
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333 题意:给以数字字符串,移动最后若干位到最前边,统计得到的数字有多少比原来大,有多少和原来同样,有多少 ...
- HDU - 4333 Revolving Digits(扩展KMP)
http://acm.hdu.edu.cn/showproblem.php?pid=4333 题意 一个数字,依次将第一位放到最后一位,问小于本身的数的个数及等于本身的个数和大于本身的个数,但是要注意 ...
随机推荐
- Eclipse调试Java的十个技巧
先提三点 不要使用System.out.println()作为调试工具 启用所有组件的详细的日志记录级别 使用一个日志分析器来阅读日志 1.条件断点 想象一下我们平时如何添加断点,通常的做法是 ...
- android 检测工具: drozer
1. 下载 https://www.mwrinfosecurity.com/products/drozer/community-edition/ 可以下载windows的也可以下载linux的 2. ...
- 【总结】java命令解析以及编译器,虚拟机如何定位类
学Java有些日子了,一直都使用IDE来写程序.这样的好处就是能让我连如何用命令行编译,解释执行Java源代码都不知道,就更不清楚JDK中的编译器和虚拟机(包含字节码解释器)是如何定位到类文件的.悲哀 ...
- 配置Linux系统网卡连接网络
本实验需要两台虚拟机来完成,环境如下: 主机名称 操作系统 ip地址 本地主机 RHEL7_64 192.168.157.134 -> 192.168.129.127 远程主机 CentOS 6 ...
- Git设置及GitHub的使用
把github上的help略略翻译一遍.备忘. First : 安装:ubuntu 下,终端输入命令: sudo apt-get install git-core git-gui git-doc Ne ...
- Delphi遍历文件夹
/// <remarks> /// 遍历文件夹 (引用SysUtils单元) /// </remarks> procedure TfrmMusicMenu.SearchInDi ...
- GitHub的使用 —— 如何删除Repository
如果要在GitHub上删除一个已经存在的Repository,该怎么办呢 ? 1.首先,点击这个资源(Repository),进入.会看到如下页面: 2.点击 Admin .在 Admin 页面的最下 ...
- 在linux系统下检查postgresql数据库安装,登录数据库及简单的查看数据库
1. 检查Linux系统是否安装数据库 首先查看自己的系统是否安装了postgresql数据库命令如下: rpm -qa | grep postgresql 如果没有显示查询结果(如下图所示)说 ...
- hihoCoder 1040 矩形判断(计算几何)
http://hihocoder.com/problemset/problem/1040 首先判断四条线段是否相交,给出八个点,如果有一些点重合,并且不同坐标的点只有4个的话,表示可以构成四边形. 然 ...
- BZOJ 1041 圆上的整点
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1041 题意:求圆x^2+y^2=r^2上的整点. 思路:由于对称性,我们只需要计算第一象 ...