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. Android上线check_list

    Android 上线 check_list 类型 序号 检查项 结果(pass/no) 安装 卸载 1 非Root环境下的安装.卸载 2 Root环境下的安装.卸载 3 安装文件检查,无泄漏用户信息的 ...

  2. SQL还原数据库

    还原一个备份数据库的经历. 首先,手头上有工程文件及相应的数据库的备份. 步骤: 1.在工程文件里找到配置文件,我这个是在bin目录里找到config.ini 2.双击打开它,里面有一些数据库的相关信 ...

  3. 霍金的新语音系统 ACAT 将开源

    英国理论物理学家斯蒂芬·霍金(Stephen Hawking)使用了二十年的语音通讯系统被英特尔开发的新一代通讯平台替代,显著改进了通讯效率.但霍金的声音并没有发生改变,他仍然使用相同的语音合成器.霍 ...

  4. 迅为IMX6Q开发板在道路交通信号控制系统解决方案中的应用

    智能交通综合管控平台是为交通指挥系统服务的统一信息平台,以信息技术为主导,以计算机通信网络和智能化指挥控制管理为基础,建成集高新技术应用为一体的智能化指挥调度集成平台,实现信息交换与共享.快速反应决策 ...

  5. UVA 1661 Equation (后缀表达式,表达式树,模拟,实现)

    题意:给出一个后缀表达式f(x),最多出现一次x,解方程f(x) = 0. 读取的时候用一个栈保存之前的结点,可以得到一颗二叉树,标记出现'X'的路径,先把没有出现'X'的子树算完,由于读取建树的时候 ...

  6. Luogu P4463 [国家集训队] calc

    WJMZBMR的题果然放在几年后看来仍然挺神,提出了一种独特的优化DP的方式 首先我们想一个暴力DP,先定下所有数的顺序(比如强制它递增),然后最后乘上\(n!\)种排列方式就是答案了 那么我们容易想 ...

  7. vue 不支持 数组Array,只支持get set push,但是正是做tab的时候,用到splice,就都不好用了,最后用v-if,从新渲染 完美解决

    vue 不支持 数组Array,只支持get set push,但是正是做tab的时候,用到splice,就都不好用了,最后用v-if,从新渲染 完美解决

  8. js 两个数组对象根据账号比较去重,解决直接splice后数组索引改变

    目的获取Arr2中不包含在arr1中的对象 根据Account进行比较,如果相等则删除tempArr数组对象. 结果返回张三 var arr1=[{"account":" ...

  9. No-12.函数进阶

    函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...

  10. Linux内核漏洞利用-环境配置(转)

    实验环境: Ubuntu-14.04.1 x86 linux-2.6.32.1 busybox-1.27.2 qemu 0x00 安装qemu sudo apt-get install qemu qe ...