http://acm.hdu.edu.cn/showproblem.php?pid=4333

【题意】

  • 给定一个数字<=10^100000,每次将该数的第一位放到放到最后一位,求所有组成的不同的数比原数小的个数,相等的个数,大的个数

【思路】

  • 这个数很大,用字符串处理
  • 比较两个字符串的大小,一位一位很耗时,可以求出最长公共前缀,只比较最长公共前缀后一位
  • 每次将数的最后一位放到最后一位,如abcd变成dabc,cdab,bcda,相当于abcdabcd各个后缀的前四位
  • 这样就变成了求abcdabcd的每个后缀与abcd的最长公共前缀,用扩展KMP线性求
  • abab这种情况按上面的做法abababab会考察ab,ba,ab,ba,有重复的,是因为abab=(ab)^2,所以还要考虑最小循环节去重

【AC】

 #include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=2e5+;
char s[maxn];
char t[maxn];
int nxt[maxn];
int extend[maxn];
int nxtval[maxn]; void pre_EKMP(char x[],int m,int nxt[])
{
nxt[]=m;
int j=;
while(j+<m && x[j]==x[j+]) j++;
nxt[]=j;
int k=;
for(int i=;i<m;i++)
{
int p=nxt[k]+k-;
int L=nxt[i-k];
if(i+L<p+) nxt[i]=L;
else
{
j=max(,p-i+);
while(i+j<m && x[i+j]==x[j]) j++;
nxt[i]=j;
k=i;
}
}
} void EKMP(char x[],int m,char y[],int n,int nxt[],int extend[])
{
pre_EKMP(x,m,nxt);//子串
int j=;
while(j<n && j<m &&x[j]==y[j]) j++;
extend[]=j;
int k=;
for(int i=;i<n;i++)
{
int p=extend[k]+k-;
int L=nxt[i-k];
if(i+L<p+) extend[i]=L;
else
{
j=max(,p-i+);
while(i+j<n && j<m && y[i+j]==x[j]) j++;
extend[i]=j;
k=i;
}
}
} void kmp_pre(char x[],int m,int nxtval[])
{
int i,j;
j=nxtval[]=-;
i=;
while(i<m)
{
if(j==-||x[i]==x[j])
{
i++;
j++;
if(x[i]!=x[j]) nxtval[i]=j;
else nxtval[i]=nxtval[j];
}
else j=nxtval[j];
} } void NextVal(char *T)
{
int i=,j=-;
nxtval[]=-;
int Tlen=strlen(T);
while(i<Tlen)
{
if(j==-||T[i]==T[j])
{
i++;
j++;
if(T[i]!=T[j]) nxtval[i]=j;
else nxtval[i]=nxtval[j];
}
else j=nxtval[j];
}
} int main()
{
int T;
scanf("%d",&T);
int cas=;
while(T--)
{
scanf("%s",s);
strcpy(t,s);
strcat(s,t);
int a,b,c;
a=b=c=;
int ls=strlen(s);
int lt=strlen(t);
EKMP(t,lt,s,ls,nxt,extend);
kmp_pre(t,lt,nxtval);
int p=lt-nxtval[lt];
int tmp=;
if(lt%p==) tmp=lt/p;
for(int i=;i<lt;i++)
{
if(extend[i]==lt) a++;
else if(s[i+extend[i]]>t[extend[i]]) c++;
else b++;
}
printf("Case %d: %d %d %d\n",++cas,b/tmp,a/tmp,c/tmp);
}
return ;
}

扩展kmp求最小循环节方法一:kmp预处理

扩展kmp计算最小循环节方法二:利用已知的next数组

【知识点】

扩展kmp的next数组与kmp数组的next含义不同,是字符串s的所有后缀和s本身的最长公共前缀

【坑点】

做这道题踩了各种坑

  • strcat函数的用法:strcat(s,s)是错误的,会T,strcat的两个参数传的是指针,就是s在内存里面的位置,这里两个s是同一个东西 第一个s变长的时候,第二个s也会变长,然后就没完没了了
  •  

【扩展kmp+最小循环节】HDU 4333 Revolving Digits的更多相关文章

  1. HDU 4333 Revolving Digits 扩张KMP

    标题来源:HDU 4333 Revolving Digits 意甲冠军:求一个数字环路移动少于不同数量 等同 于的数字 思路:扩展KMP求出S[i..j]等于S[0..j-i]的最长前缀 推断 nex ...

  2. HDU - 4333 Revolving Digits(拓展kmp+最小循环节)

    1.给一个数字字符串s,可以把它的最后一个字符放到最前面变为另一个数字,直到又变为原来的s.求这个过程中比原来的数字小的.相等的.大的数字各有多少. 例如:字符串123,变换过程:123 -> ...

  3. 扩展KMP - HDU 4333 Revolving Digits

    Revolving Digits Problem's Link Mean: 给你一个字符串,你可以将该字符串的任意长度后缀截取下来然后接到最前面,让你统计所有新串中有多少种字典序小于.等于.大于原串. ...

  4. hdu 3746 Cyclic Nacklace(kmp最小循环节)

    Problem Description CC always becomes very depressed at the end of this month, he has checked his cr ...

  5. HDU 6740 kmp最小循环节

    题意:给一个无线循环小数的前几位,给n,m 选择其中一种出现在前几位的循环节方式(a个数),循环节的长度b 使得n*a-m*b最大 样例: 2 1 12.1212 输出 6 选择2,2*1-1*1=1 ...

  6. hdu3746(kmp最小循环节)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746 题意:问在一个字符串末尾加上多少个字符能使得这的字符串首尾相连后能够循环 题解:就是利用next ...

  7. Cyclic Nacklace hdu3746 kmp 最小循环节

    题意:给出一段字符串  求最少在最右边补上多少个字符使得形成循环串(单个字符不是循环串) 自己乱搞居然搞出来了... 想法是:  如果nex[len]为0  那么答案显然是补len 否则  答案为循环 ...

  8. HDU1358 Period —— KMP 最小循环节

    题目链接:https://vjudge.net/problem/HDU-1358 Period Time Limit: 2000/1000 MS (Java/Others)    Memory Lim ...

  9. HDU3746 Cyclic Nacklace —— KMP 最小循环节

    题目链接:https://vjudge.net/problem/HDU-3746 Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others)    M ...

随机推荐

  1. jmeter常量吞吐量定时器

    jmeter常量吞吐量定时器

  2. Servlet和JSP之自定义标签学习

      此文章会讲述简单标签处理器,因为经典自定义标签处理器没有简单标签处理器方便使用,故在此不进行描述. 参考:慕课网的<JSP自定义标签>视频; <Servlet.JSP和Sprin ...

  3. nginx 编译某个模板的问题./configure: error: SSL modules require the OpenSSL library. You can either do not enable the modules, or install the OpenSSL library into the system, or build the OpenSSL library stati

    root@hett-PowerEdge-T30:/usr/local/src/nginx-1.9.8# ./configure --prefix=/usr/local/nginx  --add-mod ...

  4. vs和github同步开发步骤

    首先,这是在visual studio中使用.需要了解关于vs同步github必不可少.下载安装破解什么的先完成vs. 1. 然后安装一个vs中使用github的插件.vs自带的下载.这个是下载地址. ...

  5. 解决Errno::ENOENT: No Such File or Directory - Jekyll ~ Octopress and El Capitan

    参考http://schalkneethling.github.io/blog/2015/10/16/errno-enoent-no-such-file-or-directory-jekyll-oct ...

  6. 三、绘图和可视化之matplotlib

    #matplotlib简单绘图之plot import matplotlib.pyplot as plt a=[1,2,3] b=[10,2,30] plt.plot(a)#纵坐标为a的值,横坐标为a ...

  7. numpy中tile函数

    tile函数位于python模块numpy.lib.shape_base中,他的功能是重复某个数组. 函数的形式是tile(A,reps) 函数参数说明中提到A和reps都是array_like的,什 ...

  8. Apache Commons Configuration的应用

    Apache Commons Configuration的应用 Commons Configuration是一个java应用程序的配置管理工具.可以从properties或者xml文件中加载软件的配置 ...

  9. class extension、class category、class-continuation category

    class extension Objective-C 2.0增加了class extensions用于解决两个问题: 允许一个对象可以拥有一个私有的interface,且可由编译器验证. 支持一个公 ...

  10. ios retain copy assign相关

    assign: 简单赋值,不更改索引计数copy: 建立一个索引计数为1的对象,然后释放旧对象retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 Copy其实是建立了一 ...