POJ 2774 找出2字符串 最长公共连续子串
2013-07-14 22:37
387 查看
Long Long Message
Description
The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days: his mother is getting ill. Being worried about spending so much on railway tickets (Byterland is such a big country,
and he has to spend 16 shours on train to his hometown), he decided only to send SMS with his mother.
The little cat lives in an unrich family, so he frequently comes to the mobile service center, to check how much money he has spent on SMS. Yesterday, the computer of service center was broken, and printed two very long messages. The brilliant little cat soon
found out:
1. All characters in messages are lowercase Latin letters, without punctuations and spaces.
2. All SMS has been appended to each other – (i+1)-th SMS comes directly after the i-th one – that is why those two messages are quite long.
3. His own SMS has been appended together, but possibly a great many redundancy characters appear leftwards and rightwards due to the broken computer.
E.g: if his SMS is “motheriloveyou”, either long message printed by that machine, would possibly be one of “hahamotheriloveyou”, “motheriloveyoureally”, “motheriloveyouornot”, “bbbmotheriloveyouaaa”, etc.
4. For these broken issues, the little cat has printed his original text twice (so there appears two very long messages). Even though the original text remains the same in two printed messages, the redundancy characters on both sides would be possibly different.
You are given those two very long messages, and you have to output the length of the longest possible original text written by the little cat.
Background:
The SMS in Byterland mobile service are charging in dollars-per-byte. That is why the little cat is worrying about how long could the longest original text be.
Why ask you to write a program? There are four resions:
1. The little cat is so busy these days with physics lessons;
2. The little cat wants to keep what he said to his mother seceret;
3. POJ is such a great Online Judge;
4. The little cat wants to earn some money from POJ, and try to persuade his mother to see the doctor :(
Input
Two strings with lowercase letters on two of the input lines individually. Number of characters in each one will never exceed 100000.
Output
A single line with a single integer number – what is the maximum length of the original text written by the little cat.
Sample Input
Sample Output
Source
POJ Monthly--2006.03.26,Zeyuan Zhu,"Dedicate to my great beloved mother."
题意 :
输入2个字符串 找出2者最长公共连续子串
思路: 2个字符串放到一块找最长重复字串 注意2个子串控制在不同的字符串中
Time Limit: 4000MS | Memory Limit: 131072K | |
Total Submissions: 17576 | Accepted: 7143 | |
Case Time Limit: 1000MS |
The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to him these days: his mother is getting ill. Being worried about spending so much on railway tickets (Byterland is such a big country,
and he has to spend 16 shours on train to his hometown), he decided only to send SMS with his mother.
The little cat lives in an unrich family, so he frequently comes to the mobile service center, to check how much money he has spent on SMS. Yesterday, the computer of service center was broken, and printed two very long messages. The brilliant little cat soon
found out:
1. All characters in messages are lowercase Latin letters, without punctuations and spaces.
2. All SMS has been appended to each other – (i+1)-th SMS comes directly after the i-th one – that is why those two messages are quite long.
3. His own SMS has been appended together, but possibly a great many redundancy characters appear leftwards and rightwards due to the broken computer.
E.g: if his SMS is “motheriloveyou”, either long message printed by that machine, would possibly be one of “hahamotheriloveyou”, “motheriloveyoureally”, “motheriloveyouornot”, “bbbmotheriloveyouaaa”, etc.
4. For these broken issues, the little cat has printed his original text twice (so there appears two very long messages). Even though the original text remains the same in two printed messages, the redundancy characters on both sides would be possibly different.
You are given those two very long messages, and you have to output the length of the longest possible original text written by the little cat.
Background:
The SMS in Byterland mobile service are charging in dollars-per-byte. That is why the little cat is worrying about how long could the longest original text be.
Why ask you to write a program? There are four resions:
1. The little cat is so busy these days with physics lessons;
2. The little cat wants to keep what he said to his mother seceret;
3. POJ is such a great Online Judge;
4. The little cat wants to earn some money from POJ, and try to persuade his mother to see the doctor :(
Input
Two strings with lowercase letters on two of the input lines individually. Number of characters in each one will never exceed 100000.
Output
A single line with a single integer number – what is the maximum length of the original text written by the little cat.
Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchiloveyoumydearmother
Sample Output
27
Source
POJ Monthly--2006.03.26,Zeyuan Zhu,"Dedicate to my great beloved mother."
题意 :
输入2个字符串 找出2者最长公共连续子串
思路: 2个字符串放到一块找最长重复字串 注意2个子串控制在不同的字符串中
#include<stdio.h> #include<string.h> #include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<string> #include<string.h> using namespace std; const int nMax =210000; int num[nMax]; int sa[nMax], rank[nMax], height[nMax]; int wa[nMax], wb[nMax], wv[nMax], wd[nMax]; int mmin(int a,int b) { if(a>b) return b; return a; } int cmp(int *r, int a, int b, int l) { return r[a] == r[b] && r[a+l] == r[b+l]; } void da(int *r, int n, int m){ // 倍增算法 r为待匹配数组 n为总长度 m为字符范围 int i, j, p, *x = wa, *y = wb, *t; for(i = 0; i < m; i ++) wd[i] = 0; for(i = 0; i < n; i ++) wd[x[i]=r[i]] ++; for(i = 1; i < m; i ++) wd[i] += wd[i-1]; for(i = n-1; i >= 0; i --) sa[-- wd[x[i]]] = i; for(j = 1, p = 1; p < n; j *= 2, m = p){ for(p = 0, i = n-j; i < n; i ++) y[p ++] = i; for(i = 0; i < n; i ++) if(sa[i] >= j) y[p ++] = sa[i] - j; for(i = 0; i < n; i ++) wv[i] = x[y[i]]; for(i = 0; i < m; i ++) wd[i] = 0; for(i = 0; i < n; i ++) wd[wv[i]] ++; for(i = 1; i < m; i ++) wd[i] += wd[i-1]; for(i = n-1; i >= 0; i --) sa[-- wd[wv[i]]] = y[i]; for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i ++){ x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1: p ++; } } } void calHeight(int *r, int n){ // 求height数组。 int i, j, k = 0; for(i = 1; i <= n; i ++) rank[sa[i]] = i; // 1->n for(i = 0; i < n; i++){ for(k ? k -- : 0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k ++); height[rank[i]] = k; } } int Log[nMax]; int best[20][nMax];//best[i][j] 表示从j开始的长度为2的i次方的一段元素的最小值 void initRMQ(int n) {//初始化RMQ int i,j; for(i = 1; i <= n ; i ++) best[0][i] = height[i]; for(i = 1; i <= Log ; i ++) { int limit = n - (1<<i) + 1; for(j = 1; j <= limit ; j ++) { best[i][j] = mmin(best[i-1][j] , best[i-1][j+(1<<i>>1)]); } } } int lcp(int a,int b) {//询问a,b后缀的最长公共前缀 a = rank[a]; b = rank[b]; if(a > b) swap(a,b); a ++; int t = Log[b - a + 1]; return mmin(best[t][a] , best[t][b - (1<<t) + 1]); } void get_log() { int i; Log[0] = -1; for(i=1;i<=nMax;i++) { // 求log2,这么强大的位运算。。 Log[i]=(i&(i-1))?Log[i-1]:Log[i-1] + 1 ; } } char str[nMax]; int ans[nMax]; int a[nMax],m,n; int solve(int k) { int i,mx=0,mn=nMax; for(i=1;i<=n;i++) { if(height[i]>=k) { mx=max(mx,sa[i]); mn=min(mn,sa[i]); if(mx-mn>=k&&mn<m&&mx>=m) return 1; // if(mx-mn>=k) return 1; } else { mx=mn=sa[i]; } } return 0; } int main() { int i,j,cas=0; string s1,s2; get_log(); while(cin>>s1>>s2) { m=s1.size(); s1+=s2; strcpy(str,s1.c_str()); n=strlen(str); for(i=0;i<n;i++) num[i]=str[i]-'a'+1; num =0; da(num,n+1,30); calHeight(num,n); initRMQ(n); int left,right,mid,mx; left=1;right=n;mx=0; while(left<=right) { mid=(left+right)/2; if(solve(mid)&&mid>mx) { mx=mid; left=mid+1; } else { right=mid-1; } } printf("%d\n",mx); } return 0; }
相关文章推荐
- 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
- poj 2774 求两个字符串的最长公共子串
- POJ 2774 Long Long Message(2.3 求两个字符串的最长公共子串)
- poj 2774 Long Long Message 求两个字符串的最长公共子串 后缀数组
- poj2774 后缀数组2个字符串的最长公共子串
- poj 2774 求两个字符串的最长公共子串
- 【后缀数组】 POJ 2774 Long Long Message 两个字符串的最长公共子串长度
- POJ 3080:Blue Jeans:枚举求解n个字符串的最长公共连续子串
- poj 2774 最长公共子串--字符串hash或者后缀数组或者后缀自动机
- poj 2774 后缀数组 两个字符串的最长公共子串
- 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
- poj 2774 Long Long Message(最长公共子串)
- hdu1403 && poj 2774 最长公共子串 后缀数组
- HDU 1403 & POJ 2774 Longest Common Substring (后缀数组啊 求最长公共子串 模板题)
- poj 1226 Substrings 求n个字符串的最长公共子串(这里可以是反序相同) 后缀数组
- 找出两个字符串最长公共子串
- POJ 2774 Long Long Message(最长公共子串)
- poj 3294 求多于k个字符串的最长公共子串的个数-------后缀数组+二分答案
- 找出字符串中的最长连续数字子串
- 求两个字符串的(连续的)最长公共子串