zoukankan      html  css  js  c++  java
  • HDU 1358 next数组的推移

    题目大意:

    输入n,再输入一个长度为n的字符串,从第二位开始,计算它的前缀(包括他自己)中出现过的重复字符串的个数,如aabaabaabaab的第6位的前缀aabaab,aab连续出现了两次,所以输出位数i=6,k=2

    这个题目要利用next函数求解,不断往前推移,保证往前推移的量能被i整除。

    即del=i-next[i];

    保证i%del==0;

    其实i%del==0成立之后不用多想了,已经可以保证前面是轮回字符串了

    在此稍微进行一下理解,如next【9】=6;那么1,2,3位上的元素可以往前移3位,他们与4,5,6上的元素也是对应的。

    所以count=i/del,当count>1时将其输出

    因为我第一次没有理解,其实i%del==0成立之后不用多想了,已经可以保证前面是轮回字符串了这句话,所以仍然不断往前推移del位,其实是无用功,导至TLE

    错误代码如下:

     1 #include <iostream>
     2 #include<cstring>
     3 
     4 using namespace std;
     5 
     6 int next[1000100];
     7 char b[1000100];
     8 int n,time;
     9 void getNext(char *b)
    10 {
    11     next[0]=0,next[1]=0;
    12     int j;
    13     for(int i=1;i<n;i++)
    14     {
    15         j=next[i];
    16         while(j&&b[i]!=b[j]) j=next[j];
    17         if(b[i]==b[j]) next[i+1]=j+1;
    18         else next[i+1]=0;
    19     }
    20 }
    21 
    22 int Gcd(int a,int b)
    23 {
    24     if(b==0) return a;
    25     else return Gcd(b,a%b);
    26 }
    27 int main()
    28 {
    29     time=1;
    30     while(cin>>n&&n!=0){
    31         int t=0,del,count;
    32         for(int i=0;i<n;i++) cin>>b[i];
    33 
    34         getNext(b);
    35 
    36         cout<<"Test case #"<<time++<<endl;
    37 
    38         for(int i=2;i<=n;i++){
    39             bool judge=true;
    40             count=1;
    41             t=next[i];
    42             del=i-t;
    43             while(t){
    44                 ++count;
    45                 if(next[t]!=t-del){
    46                     judge=false;
    47                     break;
    48                 }
    49                 t=next[t];
    50             }
    51             if(judge&&count>1) cout<<i<<' '<<count<<endl;
    52         }
    53         cout<<endl;
    54     }
    55     return 0;
    56 }
    View Code

    正确代码如下:

     1 #include <iostream>
     2 #include<cstring>
     3 
     4 using namespace std;
     5 
     6 int next[1000100];
     7 char b[1000100];
     8 int n,time;
     9 void getNext(char *b)
    10 {
    11     next[0]=0,next[1]=0;
    12     int j;
    13     for(int i=1;i<n;i++)
    14     {
    15         j=next[i];
    16         while(j&&b[i]!=b[j]) j=next[j];
    17         if(b[i]==b[j]) next[i+1]=j+1;
    18         else next[i+1]=0;
    19     }
    20 }
    21 
    22 int Gcd(int a,int b)
    23 {
    24     if(b==0) return a;
    25     else return Gcd(b,a%b);
    26 }
    27 int main()
    28 {
    29     time=1;
    30     while(cin>>n&&n!=0){
    31         int t=0,del;
    32         for(int i=0;i<n;i++) cin>>b[i];
    33 
    34         getNext(b);
    35 
    36         cout<<"Test case #"<<time++<<endl;
    37 
    38         for(int i=2;i<=n;i++){
    39 
    40             t=next[i];
    41             del=i-t;
    42             if(i%del==0&&i/del>1) cout<<i<<' '<<i/del<<endl;
    43         }
    44         cout<<endl;
    45     }
    46     return 0;
    47 }
    View Code
  • 相关阅读:
    跨浏览器的事件处理程序
    jQuery提交Form
    js 多种变量定义(对象直接量,数组直接量和函数直接量)
    Asp.net Eval 截取字符串
    sql执行顺序
    IDEA File Templates模板
    Vim快捷键大全(转)
    Rider+Unity+XLua环境配置
    一定要进行代码复查
    如何在ubuntu上面安装luasocket
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3862514.html
Copyright © 2011-2022 走看看