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 }

正确代码如下:

 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 }

HDU 1358 next数组的推移

时间: 2024-12-16 16:32:57

HDU 1358 next数组的推移的相关文章

hdu 1358(KMP--next[]数组应用

Period Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 13060    Accepted Submission(s): 6102 Problem Description For each prefix of a given string S with N characters (each character has an ASCI

hdu 3948 后缀数组

The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2465    Accepted Submission(s): 841 Problem Description Now, you are given a string S. We want to know how many distin

hdu 3518 后缀数组

Boring counting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2906    Accepted Submission(s): 1201 Problem Description 035 now faced a tough problem,his english teacher gives him a string,whic

Hdu 1403(后缀数组)

题目链接 Longest Common Substring Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4077    Accepted Submission(s): 1544 Problem Description Given two strings, you have to tell the length of the Longe

poj1961 &amp; hdu 1358 Period(KMP)

poj 题目链接:http://poj.org/problem?id=1961 hdu题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358 Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether

hdu 1358 KMP next数组的运用

题意:给一个字符串,从第二个字符开始,判断前面的是不是循环串,是的话就输出当前位置和循环次数. 考的是对于next数组的理解和灵活运用,字符编号从0开始,那么if(i%(i-next[i])==0),则i前面的串为一个循环串,其中循环子串出现i/(i-next[i])次. 1 #include<iostream> 2 #include<string> 3 #include<string.h> 4 #define MAX_N 1000005 5 6 using names

(KMP 1.5)hdu 1358 Period(使用next数组来求最小循环节——求到第i个字符的循环节数)

题目: Period Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3813    Accepted Submission(s): 1862 Problem Description For each prefix of a given string S with N characters (each character has an A

HDU 1358 Period 求前缀长度和出现次数(KMP的next数组的使用)

Period Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12428    Accepted Submission(s): 5825 Problem Description For each prefix of a given string S with N characters (each character has an ASCI

Hdu 1358 Period (KMP 求最小循环节)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1358 题目描述: 给出一个字符串S,输出S的前缀能表达成Ak的所有情况,每种情况输出前缀的结束位置和k. 解题思路: 打表算出next数组,然后对位置i求循环节,如果满足 i % (i - Next[i]) == 0 && Next[i] != 0,所对应的循环节(i - Next[i]), 循环次数是i / (i - Next[i]) 1 #include<cstdio> 2