zoukankan      html  css  js  c++  java
  • hdu4333 Revolving Digits 扩展kmp

    /**
    参考:http://blog.csdn.net/acdreamers/article/details/8313828
    参考:http://www.61mon.com/index.php/archives/186/
    
    题目:hdu4333 Revolving Digits
    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333
    题意:
    给定一个数字(不含前导0),它的最后一个数字放到最前面形成一个新的数字,然后对新的数字继续处理。
    问有多少种不同的数字并原数字小,等于,大于。(注意是不同的数字,注意不是字典序大小,就是比数字大小)
    如果新数字有前导0,那么去掉0.显然该数字大小小于原数字。
    思路:
    在原数字后面连接原数字得到串t。那么i在[0,m-1],从i开始长度为m的数字就是可以转化的数字。 如果原数字有循环节,那么
    只需要计算一个最小循环节长度的结果。(通过kmp找一个字符串的最小循环节。)
    
    定义extend[i]表示t串从i开始的和原数字的最长公共前缀。
    [i,i+m-1]和原数字的比较:
    如果t[i]=='0'; 那么小于。
    如果extend[i]>=m;那么等于。
    如果extend[i]<m;如果t[i+extend[i]]>p[extend[i]] 那么大于。
    否则小于。
    
    Next[i]: T[i]...T[m - 1]与 T 的最长相同前缀长度;
    
    extend[i]: S[i]...S[n - 1]与 T 的最长相同前缀长度。
    
    
    */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include<set>
    #include <iostream>
    #include <vector>
    using namespace std;
    const int N = 2e5+10000;
    int extend[N*2], f[N], Next[N];///不可以用next[N],会编译错误。
    char t[N*2], p[N];
    void GetNext(char *T,int* next)
    {
        int a=0;
        int Tlen=strlen(T);
        next[0]=Tlen;
        while(a<Tlen-1&&T[a]==T[a+1]) a++;
        next[1]=a;
        a=1;
        for(int k=2;k<Tlen;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<Tlen&&T[k+j]==T[j]) j++;
                next[k]=j;
                a=k;
            }
            else next[k]=L;
        }
    }
    
    void GetExtend(char *S,char *T,int* next,int* extend)
    {
        int a=0;
        GetNext(T,next);
        int Slen=strlen(S);
        int Tlen=strlen(T);
        int MinLen=Slen<Tlen? Slen:Tlen;
        while(a<MinLen&&S[a]==T[a]) a++;
        extend[0]=a;
        a=0;
        for(int k=1;k<Slen;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<Slen&&j<Tlen&&S[k+j]==T[j]) j++;
                extend[k]=j;
                a=k;
            }
            else extend[k]=L;
        }
    }
    
    void getFail(char* P,int* f)
    {
        int m = strlen(P);
        f[0] = f[1] = 0;
        for(int i = 1; i < m; i++){
            int j = f[i];
            while(j&&P[i]!=P[j]) j = f[j];
            f[i+1] = (P[i]==P[j])?j+1:0;
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T;
        int cas = 1;
        cin>>T;
        while(T--){
            scanf("%s",p);
            memset(extend, 0, sizeof extend);
            int m = strlen(p);
            for(int i = 0; i < m*2; i++){
                t[i] = p[i%m];
            }
            t[2*m] = '';
            GetExtend(t,p,Next,extend);
            getFail(p,f);
            int stop = m;
            if(f[m]!=0&&m%(m-f[m])==0){
                stop = m-f[m];
            }
            int equ, big, small;
            equ = big = small = 0;
            for(int i = 0; i < m&&i<stop; i++){
                if(t[i]=='0'){
                    small++; continue;
                }
                if(extend[i]>=m){
                    equ++;
                }else
                {
                    if(t[i+extend[i]]>p[extend[i]]) big++;
                    else small++;
                }
            }
            printf("Case %d: %d %d %d
    ",cas++,small,equ,big);
        }
        return 0;
    }
  • 相关阅读:
    安装Apache提示APR not found的解决办法
    使用jQuery和CSS3实现一个数字时钟
    nodejs iconfont处理
    ios html5 长按复制文本
    Weex 开发入门
    Nginx比SRS做得好的地方
    NodeJs mysql 开启事务
    NodeJs使用Mysql模块实现事务处理
    centos7之系统优化方案
    CentOS 7 网络优化(升级内核、开启 BBR)
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7352709.html
Copyright © 2011-2022 走看看