zoukankan      html  css  js  c++  java
  • Revolving Digits HDU

    Revolving Digits

     HDU - 4333 

    题意:给一串数字,每次可以把最后一个移到最前面形成一个新的数字,问所有的数字中有多少比原数大、小、相等。

    原数字为s,长度为len,那么一共形成len数字。

    令t=s+s(连接),接下来利用扩展KMP找到t[i]对应的extend[i],然后去和s分三种情况比较。

    需要注意的是如果s串是一个循环的串,那么要减去重复的数字,这里用到可KMP,len-nex[len]是循环节的长度。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=200010;
     4 char s[maxn],t[maxn];
     5 int nex[maxn],ex[maxn];
     6 int lens,lent;
     7 int f[maxn];
     8 void getnex(char* t){
     9     nex[0]=lent;
    10     int a=0,p=0;
    11     for(int i=1;i<lent;i++){
    12         if(i>=p||i+nex[i-a]>=p){
    13             if(i>=p) p=i;
    14             while(p<lent&&t[p]==t[p-i]) p++;
    15             nex[i]=p-i;
    16             a=i;
    17         }else{
    18             nex[i]=nex[i-a];
    19         }
    20     }
    21 }
    22 
    23 void exkmp(char* s,char* t){
    24     int a=0,p=0;
    25     getnex(t);
    26     for(int i=0;i<lens;i++){
    27         if(i>=p||i+nex[i-a]>=p){
    28             if(i>=p) p=i;
    29             while(i<lens&&p-i<lent&&t[p-i]==s[p]) p++;
    30             ex[i]=p-i;
    31             a=i;
    32         }else {
    33             ex[i]=nex[i-a];
    34         }
    35     }
    36 }
    37 void getf(char* t){
    38     f[0]=f[1]=0;
    39     for(int i=1;i<lent;i++){
    40         int j=f[i];
    41         while(j&&t[i]!=t[j]) j=f[j];
    42         f[i+1]=t[i]==t[j]?j+1:0;
    43     }
    44 }
    45 int main(){
    46     int T,kase=0;
    47     scanf("%d",&T);
    48     while(T--){
    49         scanf("%s",t);
    50         lent=strlen(t);
    51         strcpy(s,t);
    52         strcat(s,t);
    53         lens=lent*2;
    54         printf("Case %d:",++kase);
    55         exkmp(s,t);
    56         int a=0,b=0,c=0;
    57         getf(t);
    58         int mod=lent-f[lent];
    59         int temp=1;
    60         if(lent%mod==0) temp=lent/mod;
    61         for(int i=0;i<lent;i++){
    62             if(ex[i]>=lent) b++;
    63             else if(s[i+ex[i]]<t[ex[i]]) a++;
    64             else if(s[i+ex[i]]>t[ex[i]]) c++;
    65         }
    66         printf(" %d %d %d
    ",a/temp,b/temp,c/temp);
    67     }
    68 }
    View Code
  • 相关阅读:
    C#中Equals和= =(等于号)的比较)(转载)
    C# 控制台应用程序输出颜色字体
    c#获取当前运行程序所在的目录
    java环境配置
    c#随机产生颜色
    Git学习
    git删除所有提交历史记录
    git忽略项gitegnore配置
    不搭建git服务器对git仓库进行局域网内共享多人合作开发项目
    搭建Git服务器-SCM-Manager
  • 原文地址:https://www.cnblogs.com/yijiull/p/7407486.html
Copyright © 2011-2022 走看看