POJ 2217 Secretary

Secretary

Time Limit: 1000ms

Memory Limit: 65536KB

This problem will be judged on PKU. Original ID: 2217
64-bit integer IO format: %lld      Java class name: Main

The basic condition of success of a political party, it is the good Election Programme. PSOS know about it, so they entrust the top secretary Juliet with this task. Because she wanted to make her work easier, she used her charm to talk round her friend Romeo to help her. Romeo is assistent of another political party and he was writing the programme some time ago. While writing the Programme for Juliet, he used some parts of his previous programme. When he gave the finished Programme to Juliet, they recognized that both programmes are too similar and that someone could notice it. They need to determine the longest part of text which is common to both programmes.

Input

At the first line there is a positive integer N stating the number of assignments to follow. Each assignment consists of exactly two lines of text, each of them contains at most 10000 characters. The end-of-line character is not considered to be a part of the text.

Output

Print a single line of text for each assignment. The line should contain the sentence "Nejdelsi spolecny retezec ma delku X." (The longest common part of text has X characters). Replace X with the length of the longest common substring of both texts.

Sample Input

2
Tady nejsou zadni mimozemstani.
Lide tady take nejsou.
Ja do lesa nepojedu.
V sobotu pojedeme na vylet.

Sample Output

Nejdelsi spolecny retezec ma delku 7.
Nejdelsi spolecny retezec ma delku 5.

Source

CTU FEE Local 1998

解题:后缀数组。将两个串S,T链接起来。然后求lcp.sa[i]和sa[i+1]不同时在S或者不同时在T中,求满足这样条件的最大lcp。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 300000;
18 int n,k,_rank[maxn],sa[maxn],lcp[maxn],tmp[maxn];
19 char ss[100010];
20 bool cmp_sa(int i,int j){
21     if(_rank[i] != _rank[j]) return _rank[i] < _rank[j];
22     int ri = i+k <= n ? _rank[i+k]:-1;
23     int rj = j+k <= n ? _rank[j+k]:-1;
24     return ri < rj;
25 }
26 void construct_sa(char *S,int *sa){
27     for(int i = 0; i <= n; i++){
28         sa[i] = i;
29         _rank[i] = i < n ? S[i]:-1;
30     }
31     for(k = 1; k <= n; k <<= 1){
32         sort(sa,sa+n+1,cmp_sa);
33         tmp[sa[0]] = 0;
34         for(int i = 1; i <= n; i++)
35             tmp[sa[i]] = tmp[sa[i-1]] + cmp_sa(sa[i-1],sa[i]);
36         for(int i = 0; i <= n; i++)
37             _rank[i] = tmp[i];
38     }
39 }
40 void construct_lcp(char *S,int *lcp){
41     for(int i = 0; i <= n; i++) _rank[sa[i]] = i;
42     int h = lcp[0] = 0;
43     for(int i = 0; i < n; i++){
44         if(h) h--;
45         for(int j = sa[_rank[i]-1]; i+h < n && j+h < n && S[i+h] == S[j+h]; ++h);
46         lcp[_rank[i]-1] = h;
47     }
48 }
49 int main() {
50     int t,slen;
51     scanf("%d",&t);
52     getchar();
53     while(t--){
54         gets(ss);
55         slen = strlen(ss);
56         ss[slen] = ‘#‘;
57         gets(ss+slen+1);
58         n = strlen(ss);
59         memset(sa,0,sizeof(sa));
60         memset(lcp,0,sizeof(lcp));
61         construct_sa(ss,sa);
62         construct_lcp(ss,lcp);
63         int ans = 0;
64         for(int i = 0; i < n; i++)
65             if((sa[i] < slen) != (sa[i+1] < slen)) ans = max(ans,lcp[i]);
66         printf("Nejdelsi spolecny retezec ma delku %d.\n",ans);
67     }
68     return 0;
69 }

时间: 2024-12-05 22:50:34

POJ 2217 Secretary的相关文章

POJ 2217 Secretary (后缀数组)

题目大意: 计算两个字符串的最长的公共字符串字串的长度. 思路分析: 将两个串合并起来. 然后直接跑后缀数组求出height 然后就可以直接扫描一次height ,加个是不是在一个串中的判断就可以了. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define maxn 200005 using namespace std; char str[ma

后缀数组 POJ 2217 Secretary

题目链接 题意:求两个字符串的最长公共子串 分析:做法是构造新的串是两个串连接而成,中间用没有出现的字符隔开(因为这样才能保证S的后缀的公共前缀不会跨出一个原有串的范围),即newS = S + '$' + T.对其求sa数组和height数组,取最小值的height[i],且两个后缀串属于不同的字符串. #include <cstdio> #include <cstring> #include <algorithm> #include <iostream>

POJ 2217:Secretary(后缀数组)

题目大意:求两个字符串的公共子串. 分析: 模板题,将两个字符串接起来用不会出现的字符分割,然后求分属两个字符串的相邻后缀lcp的最大值即可. 代码: program work; type arr=array[0..20001]of longint; var sa,rank,b,tmp,lcp:arr; n,i,m,l,u,ans,t:longint; s,s1,s2:ansistring; ch:char; function compare(i,j,k:longint):longint; va

POJ 2217 (后缀数组+最长公共子串)

题目链接: http://poj.org/problem?id=2217 题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续. 解题思路: 有个炒鸡快的O(n)的Manacher算法.不过只能求裸的最长公共和回文子串. 后缀数组解法是这类问题的模板解法. 对于n个串的最长公共子串,这要把这些串连在一起,中间用"$"这类的特殊符号分隔一下. 先求后缀数组,再求最长公共前缀,取相邻两个且属于不同串的sa的最大LCP即可. 原理就是:这样把分属两个串的LCP都跑了一遍,

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)

POJ——T2271 Guardian of Decency

http://poj.org/problem?id=2771 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5932   Accepted: 2463 Description Frank N. Stein is a very conservative high-school teacher. He wants to take some of his students on an excursion, but he is

POJ——T2446 Chessboard

http://poj.org/problem?id=2446 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18560   Accepted: 5857 Description Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of c

poj 1088 滑雪 DP(dfs的记忆化搜索)

题目地址:http://poj.org/problem?id=1088 题目大意:给你一个m*n的矩阵 如果其中一个点高于另一个点 那么就可以从高点向下滑 直到没有可以下滑的时候 就得到一条下滑路径 求最大的下滑路径 分析:因为只能从高峰滑到低峰,无后效性,所以每个点都可以找到自己的最长下滑距离(只与自己高度有关).记忆每个点的最长下滑距离,当有另一个点的下滑路径遇到这个点的时候,直接加上这个点的最长下滑距离. dp递推式是,dp[x][y] = max(dp[x][y],dp[x+1][y]+