hdu 3336
Count the string
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7242 Accepted Submission(s): 3348
Problem Description
It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of this string. For example:
s: "abab"
The prefixes are: "a", "ab", "aba", "abab"
For each prefix, we can count the times it matches in s. So we can see that prefix "a" matches twice, "ab" matches twice too, "aba" matches once, and "abab" matches once. Now you are asked to calculate the sum of the match times for all the prefixes. For "abab", it is 2 + 2 + 1 + 1 = 6.
The answer may be very large, so output the answer mod 10007.
s: "abab"
The prefixes are: "a", "ab", "aba", "abab"
For each prefix, we can count the times it matches in s. So we can see that prefix "a" matches twice, "ab" matches twice too, "aba" matches once, and "abab" matches once. Now you are asked to calculate the sum of the match times for all the prefixes. For "abab", it is 2 + 2 + 1 + 1 = 6.
The answer may be very large, so output the answer mod 10007.
Input
The first line is a single integer T, indicating the number of test cases.
For each case, the first line is an integer n (1 <= n <= 200000), which is the length of string s. A line follows giving the string s. The characters in the strings are all lower-case letters.
For each case, the first line is an integer n (1 <= n <= 200000), which is the length of string s. A line follows giving the string s. The characters in the strings are all lower-case letters.
Output
For each case, output only one number: the sum of the match times for all the prefixes of s mod 10007.
Sample Input
1 4 abab
Sample Output
6
题意:在算出前缀后暴力的话会TLE,因此考虑用kmp算法,只需要理解next的作用,用dp[i]保存到i为止前缀的数量。
状态转移方程为 dp[i]+=dp[next[i] ]
线性复杂度;
代码:
#include <cstdio>
#include <cstring>
int next[200005];
char s[200005];
inline void calnext(char s[],int next[]) {
int i,j;
int len = strlen(s);
next[0]=-1;
j=-1;
for(i=1;i<len;i++) {
while(j>=0&&s[i]!=s[j+1])
j=next[j];
if(s[j+1]==s[i])//上一个循环可能因为 j==-1 而不做,此时不能知道s[i]与s[j+1]的关系。故需要此条件
j++;
next[i]=j;
}
}
int dp[200005];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int slen;
int i,j;
memset(next,0,sizeof(next));
scanf("%d",&slen);
scanf("%s",s);
calnext(s,next);
for(i=0;i<=slen;i++)
dp[i]=1;
int ans=0;
for(i=0;i<slen;i++)
{
dp[i]+=dp[next[i]];
ans+=dp[i];
ans%=10007;
}
printf("%d\n",ans);
}
return 0;
}
hdu 3746
Cyclic Nacklace
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5134 Accepted Submission(s): 2321
Problem Description
CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, without any surprise, there are only 99.9 yuan left. he is too distressed and thinking about how to tide over the last days. Being inspired by the entrepreneurial spirit of "HDU CakeMan", he wants to sell some little things to make money. Of course, this is not an easy task.
As Christmas is around the corner, Boys are busy in choosing christmas presents to send to their girlfriends. It is believed that chain bracelet is a good choice. However, Things are not always so simple, as is known to everyone, girl's fond of the colorful decoration to make bracelet appears vivid and lively, meanwhile they want to display their mature side as college students. after CC understands the girls demands, he intends to sell the chain bracelet called CharmBracelet. The CharmBracelet is made up with colorful pearls to show girls' lively, and the most important thing is that it must be connected by a cyclic chain which means the color of pearls are cyclic connected from the left to right. And the cyclic count must be more than one. If you connect the leftmost pearl and the rightmost pearl of such chain, you can make a CharmBracelet. Just like the pictrue below, this CharmBracelet's cycle is 9 and its cyclic count is 2:
Now CC has brought in some ordinary bracelet chains, he wants to buy minimum number of pearls to make CharmBracelets so that he can save more money. but when remaking the bracelet, he can only add color pearls to the left end and right end of the chain, that is to say, adding to the middle is forbidden.
CC is satisfied with his ideas and ask you for help.
As Christmas is around the corner, Boys are busy in choosing christmas presents to send to their girlfriends. It is believed that chain bracelet is a good choice. However, Things are not always so simple, as is known to everyone, girl's fond of the colorful decoration to make bracelet appears vivid and lively, meanwhile they want to display their mature side as college students. after CC understands the girls demands, he intends to sell the chain bracelet called CharmBracelet. The CharmBracelet is made up with colorful pearls to show girls' lively, and the most important thing is that it must be connected by a cyclic chain which means the color of pearls are cyclic connected from the left to right. And the cyclic count must be more than one. If you connect the leftmost pearl and the rightmost pearl of such chain, you can make a CharmBracelet. Just like the pictrue below, this CharmBracelet's cycle is 9 and its cyclic count is 2:
Now CC has brought in some ordinary bracelet chains, he wants to buy minimum number of pearls to make CharmBracelets so that he can save more money. but when remaking the bracelet, he can only add color pearls to the left end and right end of the chain, that is to say, adding to the middle is forbidden.
CC is satisfied with his ideas and ask you for help.
Input
The first line of the input is a single integer T ( 0 < T <= 100 ) which means the number of test cases.
Each test case contains only one line describe the original ordinary chain to be remade. Each character in the string stands for one pearl and there are 26 kinds of pearls being described by 'a' ~'z' characters. The length of the string Len: ( 3 <= Len <= 100000 ).
Each test case contains only one line describe the original ordinary chain to be remade. Each character in the string stands for one pearl and there are 26 kinds of pearls being described by 'a' ~'z' characters. The length of the string Len: ( 3 <= Len <= 100000 ).
Output
For each case, you are required to output the minimum count of pearls added to make a CharmBracelet.
Sample Input
3 aaa abca abcde
Sample Output
0 2 5
思路 可以通过求 flen= slen-next[slen-1]-1; 来求得循环节
之后只要特判一下 长度整除循环节的情况就行;
不整除就补齐;
代码:
#include <cstdio>
#include <cstring>
int next[100005];
char s[100005]; char t[100005];
inline void calnext(char s[],int next[]) {
int i,j;
int len = strlen(s);
next[0]=-1;
j=-1;
for(i=1;i<len;i++) {
while(j>=0&&s[i]!=s[j+1])
j=next[j];
if(s[j+1]==s[i])//上一个循环可能因为 j==-1 而不做,此时不能知道s[i]与s[j+1]的关系。故需要此条件
j++;
next[i]=j;
}
}
int main() {
int n;
scanf("%d",&n);
while(n--) {
scanf("%s",s); //s代表短串,t代表长串
int slen=strlen(s);
calnext(s,next);
int flen= slen-next[slen-1]-1; //循环节
if (flen!=slen&&(slen%flen==0))
{
printf("0\n");
continue;
}
int num=slen/flen;
printf("%d\n",(num+1)*flen-slen);
}
return 0;
}
hdu 1358
Period
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5394 Accepted Submission(s): 2601
Problem 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 the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as A
K , that is A concatenated K times, for some string A. Of course, we also want to know the period K.
Input
The input file consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S. The second line contains the string S. The input file ends with a line, having the number zero on it.
Output
For each test case, output “Test case #” and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.
Sample Input
3 aaa 12 aabaabaabaab 0
Sample Output
Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4
同样是求循环节;
代码:
#include <cstdio>
#include <cstring>
int next[1005000];
char s[1005000]; char t[1005000];
inline void calnext(char s[],int next[]) {
int i,j;
int len = strlen(s);
next[0]=-1;
j=-1;
for(i=1;i<len;i++) {
while(j>=0&&s[i]!=s[j+1])
j=next[j];
if(s[j+1]==s[i])//上一个循环可能因为 j==-1 而不做,此时不能知道s[i]与s[j+1]的关系。故需要此条件
j++;
next[i]=j;
}
}
int main() {
int n;
int ncase=1;
while( scanf("%d",&n)!=EOF)
{
if(!n)
return 0;
scanf("%s",s);
int slen=strlen(s);
calnext(s,next);
printf("Test case #%d\n",ncase++);
for(int i=2;i<=slen;i++)
{
int flen=i-next[i-1]-1;
if(i%flen==0&&flen!=i)
printf("%d %d\n",i,i/flen);
}
printf("\n");
}
return 0;
}
hdu2594
Simpsons’ Hidden Talents
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5340 Accepted Submission(s): 1937
Problem Description
Homer: Marge, I just figured out a way to discover some of the talents we weren’t aware we had.
Marge: Yeah, what is it?
Homer: Take me for example. I want to find out if I have a talent in politics, OK?
Marge: OK.
Homer: So I take some politician’s name, say Clinton, and try to find the length of the longest prefix
in Clinton’s name that is a suffix in my name. That’s how close I am to being a politician like Clinton
Marge: Why on earth choose the longest prefix that is a suffix???
Homer: Well, our talents are deeply hidden within ourselves, Marge.
Marge: So how close are you?
Homer: 0!
Marge: I’m not surprised.
Homer: But you know, you must have some real math talent hidden deep in you.
Marge: How come?
Homer: Riemann and Marjorie gives 3!!!
Marge: Who the heck is Riemann?
Homer: Never mind.
Write a program that, when given strings s1 and s2, finds the longest prefix of s1 that is a suffix of s2.
Marge: Yeah, what is it?
Homer: Take me for example. I want to find out if I have a talent in politics, OK?
Marge: OK.
Homer: So I take some politician’s name, say Clinton, and try to find the length of the longest prefix
in Clinton’s name that is a suffix in my name. That’s how close I am to being a politician like Clinton
Marge: Why on earth choose the longest prefix that is a suffix???
Homer: Well, our talents are deeply hidden within ourselves, Marge.
Marge: So how close are you?
Homer: 0!
Marge: I’m not surprised.
Homer: But you know, you must have some real math talent hidden deep in you.
Marge: How come?
Homer: Riemann and Marjorie gives 3!!!
Marge: Who the heck is Riemann?
Homer: Never mind.
Write a program that, when given strings s1 and s2, finds the longest prefix of s1 that is a suffix of s2.
Input
Input consists of two lines. The first line contains s1 and the second line contains s2. You may assume all letters are in lowercase.
Output
Output consists of a single line that contains the longest string that is a prefix of s1 and a suffix of s2, followed by the length of that prefix. If the longest such string is the empty string, then the output should be 0.
The lengths of s1 and s2 will be at most 50000.
The lengths of s1 and s2 will be at most 50000.
Sample Input
clinton homer riemann marjorie
Sample Output
0 rie 3
可以先把后面的那串字符串接到前面的字符串的后面也可以直接算;
#include <stdio.h>
#include <string.h>
char str1[50005],str2[50005];
int next[50005];
void get_next(int len2)
{
int i = 0,j = -1;
next[0] = -1;
while(i<len2)
{
if(j == -1 || str2[i] == str2[j])
{
j++;
i++;
if(str2[i] == str2[j])
next[i] = next[j];
else
next[i] = j;
}
else
j = next[j];
}
}
int kmp(int len1,int len2)
{
int i = 0,j = 0;
get_next(len2);
while(i<len1)
{
if(j == -1 || str1[i] == str2[j])
{
i++;
j++;
}
else
j = next[j];
}
return j;
}
int main()
{
int i,len1,len2,n;
while(gets(str2))
{
gets(str1);
len1 = strlen(str1);
len2 = strlen(str2);
n = kmp(len1,len2);
for(i = 0; i<n; i++)
putchar(str2[i]);
if(n)
printf(" ");
printf("%d\n",n);
}
return 0;
}
总结:
以前一直觉得kmp的next写的太差了,sunday完爆之。现在才发现写的烂的next才有用=,=