【扩展kmp+最小循环节】HDU 4333 Revolving Digits
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含义不同,是字符串s的所有后缀和s本身的最长公共前缀
【坑点】
做这道题踩了各种坑
- strcat函数的用法:strcat(s,s)是错误的,会T,strcat的两个参数传的是指针,就是s在内存里面的位置,这里两个s是同一个东西 第一个s变长的时候,第二个s也会变长,然后就没完没了了
【扩展kmp+最小循环节】HDU 4333 Revolving Digits的更多相关文章
- HDU 4333 Revolving Digits 扩张KMP
标题来源:HDU 4333 Revolving Digits 意甲冠军:求一个数字环路移动少于不同数量 等同 于的数字 思路:扩展KMP求出S[i..j]等于S[0..j-i]的最长前缀 推断 nex ...
- HDU - 4333 Revolving Digits(拓展kmp+最小循环节)
1.给一个数字字符串s,可以把它的最后一个字符放到最前面变为另一个数字,直到又变为原来的s.求这个过程中比原来的数字小的.相等的.大的数字各有多少. 例如:字符串123,变换过程:123 -> ...
- 扩展KMP - HDU 4333 Revolving Digits
Revolving Digits Problem's Link Mean: 给你一个字符串,你可以将该字符串的任意长度后缀截取下来然后接到最前面,让你统计所有新串中有多少种字典序小于.等于.大于原串. ...
- hdu 3746 Cyclic Nacklace(kmp最小循环节)
Problem Description CC always becomes very depressed at the end of this month, he has checked his cr ...
- HDU 6740 kmp最小循环节
题意:给一个无线循环小数的前几位,给n,m 选择其中一种出现在前几位的循环节方式(a个数),循环节的长度b 使得n*a-m*b最大 样例: 2 1 12.1212 输出 6 选择2,2*1-1*1=1 ...
- hdu3746(kmp最小循环节)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746 题意:问在一个字符串末尾加上多少个字符能使得这的字符串首尾相连后能够循环 题解:就是利用next ...
- Cyclic Nacklace hdu3746 kmp 最小循环节
题意:给出一段字符串 求最少在最右边补上多少个字符使得形成循环串(单个字符不是循环串) 自己乱搞居然搞出来了... 想法是: 如果nex[len]为0 那么答案显然是补len 否则 答案为循环 ...
- HDU1358 Period —— KMP 最小循环节
题目链接:https://vjudge.net/problem/HDU-1358 Period Time Limit: 2000/1000 MS (Java/Others) Memory Lim ...
- HDU3746 Cyclic Nacklace —— KMP 最小循环节
题目链接:https://vjudge.net/problem/HDU-3746 Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others) M ...
随机推荐
- Ubuntu 14.04 配置confluence破解
1. 配置java环境,请参展我的另一篇博客 http://www.cnblogs.com/youran-he/p/8607155.html 2. 下载文件 https://pan.baidu.com ...
- Python之Mac Scrapy爬虫小记
最近在尝试用Python爬虫,在装Scrapy的过程中遇到了一些麻烦. 上网搜索资料也未能解决command not found scrapy的报错. 最后我删除scrapy,用pip3.6 inst ...
- Web中打印的各种方案参考
http://blog.csdn.net/chinahuyong/article/details/42527491
- react native在xcode真机调试ios
1修改URL地址:打开项目目录下的AppDelegate.m文件,修改里面的URL,把localhost改为你的电脑的IP.在Mac系统下,你可以在系统设置/网络里找到电脑的IP地址. 2选择设备:把 ...
- Swift在1.2版本的变化
从Xcode 6.3 Beta Release Notes看出,Xcode 6.3 Beta包含了很多颇为值得开发者期待的改变,共计50多处改动,同时修改了Objective-C的语法,足见苹果对Sw ...
- HDU - 4802 - GPA (水题)
题意: 计算GPA,输入一个数字和一个字符串,用 数字×字符串对应的数值 思路: 用map对应数值,要注意的是字符串为P或者N的时候,不计入结果 代码: #include<iostream> ...
- PHP 线上项目 无法操作
部署到线上的项目,http 环境没有问题,首页展示没有问题,但是跳转页面展示到了本地, 解决办法 : 更改文件夹所属用户 chown -R apache:apache html
- 【Java_基础】Java内部类详解
1.四种内部类 java中的四种内部类:成员内部类.静态内部类.局部内部类和匿名内部类.其中匿名内部类用到的最多. 1.1.成员内部类 若一个类定义在另一个类的内部作为实例成员,我们把这个作为实例成员 ...
- fsm三种建模思路比较
==================================================================================================== ...
- js,jq,php使用正则方法
1.js使用正则表达式案例: <script> var str=”543535364565@qq.com”; var res=“/^\d*@(QQ|qq|136)\.(com|cn)$/” ...