zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Binary Tree Maximum Path Sum
    ZigZag Conversion
    Longest Common Prefix
    Reverse Linked List II
    Populating Next Right Pointers in Each Node
    Populating Next Right Pointers in Each Node II
    Rotate List
    Path Sum II
    [Leetcode]-- Gray Code
    Subsets II
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4943586.html
Copyright © 2011-2022 走看看