• HDU


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

    例如:字符串123,变换过程:123 -> 312 -> 231 -> 123

    因为:312>123, 231>123, 123=123

    所以答案是:0 1 2

    2、令str1=s,str2=s+s,然后str1作为子串,str2作为主串,进行扩展kmp求出str2[i...len2-1]与str1[0...len1-1]的最长公共前缀。当公共前缀==len1时,两个数相等;否则,只须比较公共前缀后的下一个字符就能判断大小了。

    注意当中有重复的情况,只有当s有循环节的时候才会出现,先求出s的最小循环节,然后用s的长度除以最小循环节得到循环节的个数,将3个结果都除以循环节个数即可。

    3、

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    #define MaxSize 200005
    
    int _next[MaxSize],extend[MaxSize];
    
    //扩展kmp
    //next[i]:x[i...m-1]与x[0...m-1]的最长公公前缀
    //extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀
    void pre_EKMP(char x[],int m,int _next[]){//m长度
        _next[0]=m;
        int j=0;
        while(j+1<m&&x[j]==x[j+1])j++;
        _next[1]=j;
        int k=1;
        for(int i=2;i<m;i++){
            int p=_next[k]+k-1;
            int L=_next[i-k];
            if(i+L<p+1)_next[i]=L;
            else{
                j=max(0,p-i+1);
                while(i+j<m&&x[i+j]==x[j])j++;
                _next[i]=j;
                k=i;
            }
        }
    }
    
    void EKMP(char x[],int m,char y[],int n,int _next[],int extend[]){//x子串,m子串长度,y主串,n主串长度
        pre_EKMP(x,m,_next);
        int j=0;
        while(j<n&&j<m&&x[j]==y[j])j++;
        extend[0]=j;
        int k=0;
        for(int i=1;i<n;i++){
            int p=extend[k]+k-1;
            int L=_next[i-k];
            if(i+L<p+1)extend[i]=L;
            else{
                j=max(0,p-i+1);
                while(i+j<n&&j<m&&y[i+j]==x[j])j++;
                extend[i]=j;
                k=i;
            }
        }
    }
    /*
    子串  :a b a b
    主串  :a b a b a c
    next  :4 0 2 0
    extend:4 0 3 0 1 0
    */
    void GetNext(char t[]){//求next数组
        int j,k,len;
        j=0;//从0开始,首先求_next[1]
        k=-1;//比较指针
        _next[0]=-1;//初始值-1
        len=strlen(t);
        while(j<len){
            if(k==-1||t[j]==t[k]){//指针到头了,或者相等
                ++j;
                ++k;
                _next[j]=k;//此句可由优化替代
                /*优化(求匹配位置时可用)
                if(t[j]!=t[k])_next[j]=k;
                else _next[j]=_next[k];
                //*/
            }
            else k=_next[k];
        }
    }
    int main(){
        char str1[100005],str2[200005];//子串,主串
        int i,j,len1,len2;//子串长度,主串长度
        int T;
        int sumL,sumE,sumG;
        scanf("%d",&T);
        for(i=1;i<=T;++i){
            sumL=sumE=sumG=0;
            scanf("%s",str1);
            strcpy(str2,str1);
            strcat(str2,str1);
            len1=strlen(str1);
            len2=strlen(str2);
            EKMP(str1,len1,str2,len2,_next,extend);
            for(j=0;j<len1;++j){
                if(extend[j]==len1)++sumE;
                else if(str2[j+extend[j]]<str1[extend[j]])++sumL;
                else ++sumG;
            }
            GetNext(str1);
            int repetend=len1-_next[len1];//最小循环节
            int numR;//循环节的个数
            if(len1%repetend==0)numR=len1/repetend;
            else numR=1;
            printf("Case %d: %d %d %d
    ",i,sumL/numR,sumE/numR,sumG/numR);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    IE8中li添加float属性,中英数字混合BUG
    jQuery ajax get与post后台交互中的奥秘
    BZOJ 4816 数字表格
    BZOJ 1598 牛跑步
    BZOJ 4077 Messenger
    相关分析 BZOJ 4821
    Crash的数字表格 BZOJ 2154 / jzptab BZOJ 2693
    回文串 BZOJ 3676
    古代猪文 BZOJ 1951
    树上的路径 BZOJ 3784
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4943586.html
Copyright © 2020-2023  润新知