【链接】http://acm.hdu.edu.cn/showproblem.php?pid=4333


【题意】


就是给你一个数字,然后把最后一个数字放到最前面去,经过几次变换后又回到原数字,问在这些数字中,比原数字小的,相等的,大的分别有多少个。比如341-->134-->413-->341,所以和原数字相比,比原数字小的有一个,相等的有一个,大的有一个,要去重

【题解】


把原数字在右边复制一份,合成一个长度为2len的字符串T,然后做一下扩展KMP.算出T的每个位置的extend[i]值;
在extend[1..len]中,如果extend[i]>=len,就表明从这个位置开始的长度为len的字符串和原串是一样的,否则,比较
T[extend[i]]和T[i+extend[i]]的大小就能比较出大小了.
(也即从高位开始比较);
这样的复制字符的方式能够得到所有的len个数字.
但是这样还没有去掉重复的情况;
比如
1212
复制成了12121212
取的时候会取出以下4个字符串
1212
2121 1212 2121
也即每个数字会重复出现两次;
这个重复出现的次数,和原字符的最小循环节出现的次数对应;
也即len/(len-Next[len]) 当len%(len-Next[len])==0时
否则每个数字只出现一次。
(也即没有循环子串)
最小循环节的讲解在这KMP求最小循环节
扩展KMP算法的Next数组和原KMP算法的Next数组是不一样的。

【错的次数】


0

【反思】


扩展KMP的应用

【代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define ri(x) scanf("%d",&x)
#define rl(x) scanf("%lld",&x)
#define rs(x) scanf("%s",x)
#define oi(x) printf("%d",x)
#define ol(x) printf("%lld",x)
#define oc putchar(' ')
#define os(x) printf(x)
#define all(x) x.begin(),x.end()
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0); const int N=20e4;
int Next[N+10],extend[N+10],lens,lent,f[N];
char S[N+10],T[N+10]; void makenext(int m){
int a = 0;
Next[0] = lens;
while(a < lens - 1 && S[a] == S[a + 1]) a++;
Next[1] = a;
a = 1;
for(int k = 2; k < lens; 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 < lens && S[k + j] == S[j]) j++;
Next[k] = j;
a = k;
} else
Next[k] = L;
}
} void GetNext(const char *T){
int a=0;
int MinLen = lens < lent ? lens : lent;
while(a < MinLen && S[a] == T[a] ) a++;
extend[0]=a;
a=0;
for(int k=1;k < lent;k++){
int p=a+extend[a]-1,L = Next[k-a];
if((k-1)+L>=p){
int j=(p-k+1)>0? (p-k+1):0;
while(k + j < lent && T[k+j] == S[j]) j++;
extend[k]=j;
a=k;
}
else extend[k]=L;
}
} void getf(const char *s){
f[0] = 0,f[1] = 0;
int j = 0;
rep1(i,1,lens-1){
while (j > 0 && s[i]!=s[j]) j = f[j];
f[i+1] = (s[i]==s[j]?++j:0);
}
} int main(){
//Open();
int TT,kk = 0;
ri(TT);
while (TT--){
rs(S);
lens = strlen(S),lent = 2*lens;
makenext(lens);
getf(S);
int ju = lens-f[lens],tt;
if (lens%ju==0)
tt = lens/ju;
else
tt = 1;
rep1(i,0,lens-1)
T[i] = S[i];
rep1(i,lens,2*lens-1)
T[i] = T[i-lens];
GetNext(T);
int a = 0,b = 0,c = 0;
rep1(i,0,lens-1)
if (extend[i]>=lens)
b++;
else if (S[extend[i]] < T[i+extend[i]])
a++;
else if (S[extend[i]] > T[i+extend[i]])
c++;
os("Case ");oi(++kk);os(": ");oi(c/tt);oc;oi(b/tt);oc;oi(a/tt);
puts("");
}
return 0;
}

【hdu 4333】Revolving Digits的更多相关文章

  1. HDU - 4333 :Revolving Digits (扩展KMP经典题,问旋转后有多少个不同的数字小于它本身,等于它本身,大于它本身。)

    One day Silence is interested in revolving the digits of a positive integer. In the revolving operat ...

  2. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  3. 【HDU 5647】DZY Loves Connecting(树DP)

    pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...

  4. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  5. 【HDU 2196】 Computer(树的直径)

    [HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...

  6. 【HDU 2196】 Computer (树形DP)

    [HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...

  7. 【HDU 5145】 NPY and girls(组合+莫队)

    pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...

  8. 【HDU4333】Revolving Digits(扩展KMP+KMP)

    Revolving Digits   Description One day Silence is interested in revolving the digits of a positive i ...

  9. 【hdu 1043】Eight

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...

随机推荐

  1. Understanding IIS Bindings, Websites, Virtual Directories, and lastly Application Pools

    In a recent meeting, some folks on my team needed some guidance on load testing the Web application ...

  2. thinkphp中cookie和session中操作数组的方法

    thinkphp中cookie和session中操作数组的方法 一.ThinkPHP模板中如何操作session,以及如果session中保存的是数组的情况 在ThinkPHP的模板中操作sessio ...

  3. Mysql数据库常规操作(建表、查询)

    一.表单操作 1-1.创建表 create table tb_name( id in primary key auto_increment);    1-2.查看表 desc table_name; ...

  4. 织梦DedeCMS会员登录或退出后如何直接跳转到首页

    织梦dedecms默认情况下的会员登录后会直接跳转到会员中心,退出也是一样,但是如果我们想让会员登录后直接跳转到首页,那该如何实现呢? 经过我们的研究,已经找到解决办法,下面是详细的修改步骤: 首先在 ...

  5. MOOC使用心得

    1. Mooctest 使用心得 慕测平台是编程类考试和练习的服务平台,教师可以轻松监管考试流程,学生可以自由练习编程.系统负责编程练习的自动化评估及可视化展现,配合当下红火的MOOC慕课课程,慕测平 ...

  6. Mybatis使用注解进行增删改查

    // 增public interface StudentMapper{ @Insert("insert into student (stud_id, name, email, addr_id ...

  7. LoadRunner使用教程

    1.了解Loadrunner 1.1 LoadRunner 组件有哪些? LoadRunner 包含下列组件: ➤ 虚拟用户生成器用于捕获最终用户业务流程和创建自动性能测试脚本(也称为虚拟用户脚本). ...

  8. Node.js转化GBK编码 - iconv-lite

    node当使用node获取GBK编码的数据时,nodejs仅仅支持utf-8,node没有提供转换编码的原生支持,有倒是有一个模块iconv能干这个事,但须要本地方法,VC++库的支持.国外有个大牛写 ...

  9. C++ Primer高速入门之六:数组和指针

    更新:勘误,delete [] 猪 我们知道,C语言以及早期的面向结构的语言差点儿都支持数组定义.比方整形数组int 女神[2].表示有俩数: 女神[0], 女神[1].她们都是整数. C++ 语言为 ...

  10. ubuntu 分屏工具

    本文提到的分屏工具,均可通过sudo apt-get install的方式进行安装: 基本:terminator 高级:tmux,screen 还可进一步使用:ctrl + superkey + 方向 ...