URAL 1297. Palindrome(字尾陣列求最大回文串)
題目大意:給你一串字串,讓你求出來它存在的最長連續的迴文串。
解題思路:先把字串逆序加到陣列中,然後用字尾陣列求解。兩種方法:1,列舉排名,直接比較rank相同的字串的位置差是不是len。如果是的話,就記錄求解;2,列舉地址,求第i地址與第2*len-i+1的lcp的最大值。
PS:需要注意如果多解輸出靠前的字串。
兩種寫法寫在了一起,分別是Del,和Del1函式。
1297. Palindrome
Time limit: 1.0 second
Memory limit: 64 MB
Memory limit: 64 MB
The “U.S. Robots” HQ has just received a rather alarming anonymous letter. It states that the agent from the competing «Robots Unlimited» has infiltrated into “U.S. Robotics”. «U.S. Robots» security
service would have already started an undercover operation to establish the agent’s identity, but, fortunately, the letter describes communication channel the agent uses. He will publish articles containing stolen data to the “Solaris” almanac. Obviously,
he will obfuscate the data, so “Robots Unlimited” will have to use a special descrambler (“Robots Unlimited” part number NPRx8086, specifications are kept secret).
Having read the letter, the “U.S. Robots” president recalled having hired the “Robots Unlimited” ex-employee John Pupkin. President knows he can trust John, because John is still angry at being mistreated
by “Robots Unlimited”. Unfortunately, he was fired just before his team has finished work on the NPRx8086 design.
So, the president has assigned the task of agent’s message interception to John. At first, John felt rather embarrassed, because revealing the hidden message isn’t any easier than finding a needle in
a haystack. However, after he struggled the problem for a while, he remembered that the design of NPRx8086 was still incomplete. “Robots Unlimited” fired John when he was working on a specific module, the text direction detector. Nobody else could finish that
module, so the descrambler will choose the text scanning direction at random. To ensure the correct descrambling of the message by NPRx8086, agent must encode the information in such a way that the resulting secret message reads the same both forwards and
backwards.
In addition, it is reasonable to assume that the agent will be sending a very long message, so John has simply to find the longest message satisfying the mentioned property.
In addition, it is reasonable to assume that the agent will be sending a very long message, so John has simply to find the longest message satisfying the mentioned property.
Your task is to help John Pupkin by writing a program to find the secret message in the text of a given article. As NPRx8086 ignores white spaces and punctuation marks, John will remove them from the
text before feeding it into the program.
Input
The input consists of a single line, which contains a string of Latin alphabet letters (no other characters will appear in the string). String length will not exceed 1000 characters.
Output
The longest substring with mentioned property. If there are several such strings you should output the first of them.
Sample
input | output |
---|---|
ThesampletextthatcouldbereadedthesameinbothordersArozaupalanalapuazorA |
ArozaupalanalapuazorA |
Problem Author: Eugene Krokhalev
Problem Source: IX Open Collegiate Programming Contest of the High School Pupils (13.03.2004)
Problem Source: IX Open Collegiate Programming Contest of the High School Pupils (13.03.2004)
Tags:
)#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <map>
#include <set>
#define eps 1e-9
///#define M 1000100
///#define LL __int64
#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)
#define mod 1000000007
#define Read() freopen("autocomplete.in","r",stdin)
#define Write() freopen("autocomplete.out","w",stdout)
#define Cin() ios::sync_with_stdio(false)
using namespace std;
inline int read()
{
char ch;
bool flag = false;
int a = 0;
while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));
if(ch != '-')
{
a *= 10;
a += ch - '0';
}
else
{
flag = true;
}
while(((ch = getchar()) >= '0') && (ch <= '9'))
{
a *= 10;
a += ch - '0';
}
if(flag)
{
a = -a;
}
return a;
}
void write(int a)
{
if(a < 0)
{
putchar('-');
a = -a;
}
if(a >= 10)
{
write(a / 10);
}
putchar(a % 10 + '0');
}
const int maxn = 20050;
int wa[maxn], wb[maxn], wv[maxn], ws1[maxn];
int sa[maxn];
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 *sa, int n, int m)
{
int i, j, p, *x = wa, *y = wb;
for(i = 0; i < m; i++) ws1[i] = 0;
for(i = 0; i < n; i++) ws1[x[i] = r[i]]++;
for(i = 1; i < m; i++) ws1[i] += ws1[i-1];
for(i = n-1; i >= 0; i--) sa[--ws1[x[i]]] = i;
for(j = 1, p = 1; p < n; j <<= 1, 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++) ws1[i] = 0;
for(i = 0; i < n; i++) ws1[wv[i]]++;
for(i = 1; i < m; i++) ws1[i] += ws1[i-1];
for(i = n-1; i >= 0; i--) sa[--ws1[wv[i]]] = y[i];
for(swap(x, y), 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++;
}
}
int rank[maxn], height[maxn];
void calheight(int *r, int *sa, int n)
{
int i, j, k = 0;
for(i = 1; i <= n; i++) rank[sa[i]] = i;
for(int i = 0; i < n; height[rank[i++]] = k)
for(k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);
return ;
}
int dp[maxn][30];
void RMQ(int len)
{
for(int i = 1; i <= len; i++)
dp[i][0] = height[i];
for(int j = 1; 1<<j <= maxn; j++)
{
for(int i = 1; i+(1<<j)-1 <= len; i++)
dp[i][j] = min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
}
}
int lg[maxn];
int querry(int l, int r)
{
int k = lg[r-l+1];
return min(dp[l][k], dp[r-(1<<k)+1][k]);
}
void init()
{
lg[0] = -1;
for (int i = 1; i < maxn; ++i)
lg[i] = lg[i>>1] + 1;
}
char str[maxn];
int seq[maxn];
void Del1(int n)
{
int Max = 0;
int pos = 0;
for(int i = 0; i < n; i++)
{
int l = rank[i];
int r = rank[2*n-i+1];
if(l > r) swap(l, r);
int tmp = querry(l+1, r);
if(tmp*2 > Max)
{
Max = tmp*2;
pos = i;
}
l = rank[i];
r = rank[2*n-i];
if(l > r) swap(l, r);
tmp = querry(l+1, r);
if(tmp*2-1 > Max)
{
Max = tmp*2-1;
pos = i;
}
}
for (int i = pos-Max/2; Max--; ++i)
putchar(seq[i]);
puts("");
return ;
}
void Del(int n, int len)
{
int Max = 1;
int pos = 0;
for(int i = 1; i <= n; i++)
{
int tmp = height[i];
int l = sa[i-1];
int r = sa[i];
if(l > r) swap(l, r);
if(l >= len || r <= len) continue;
if(l+tmp != n-r) continue;
if(tmp > Max)
{
Max = tmp;
pos = l;
}
else if(tmp == Max && l < pos)
pos = l;
}
for(int i = pos, ans = 0; ans < Max; i++, ans++)
printf("%c",seq[i]);
puts("");
return ;
}
int main()
{
///init();
while(~scanf("%s", str))
{
int len = strlen(str);
int ans = 0;
for(int i = 0; i < len; i++) seq[ans++] = str[i];
seq[ans++] = 1;
for(int i = len-1; i >= 0; i--) seq[ans++] = str[i];
seq[ans] = 0;
int Len = ans;
da(seq, sa, Len+1, 128);
calheight(seq, sa, Len);
Del(ans, len);///列舉位置,判斷lcp是否為位置差;
///Del1(len);///列舉位置,判斷區間的lcp;
}
return 0;
}
相關文章
- ural 1297 最長迴文子串 字尾陣列陣列
- POJ 3294 Life Forms(字尾陣列求k個串的最長子串)ORM陣列
- SPOJ 694 求一個字串有多少子串 字尾陣列字串陣列
- POJ 2217-Secretary(字尾陣列+高度陣列-最大公共子串長度)陣列
- SPOJ 687. Repeats(字尾陣列求最長重複子串)陣列
- poj 2774 求兩字串的最長公共子串 字尾陣列字串陣列
- POJ 2774-Long Long Message(字尾陣列+高度陣列-最大公共子串長度)陣列
- POJ 3693 Maximum repetition substring(字尾陣列求最長重複子串)陣列
- POJ 1743 Musical Theme (字尾陣列,求最長不重疊重複子串)陣列
- 字尾陣列模板陣列
- 字尾陣列 SA陣列
- 字尾陣列複習陣列
- 字尾陣列(後續)陣列
- 字尾陣列詳解陣列
- 【筆記】字尾陣列筆記陣列
- 陣列1——求一個陣列的最大子陣列陣列
- SPOJ 220. Relevant Phrases of Annihilation(字尾陣列多次不重疊子串)陣列
- 字尾陣列學習筆記陣列筆記
- 學習筆記----字尾陣列筆記陣列
- 字尾陣列 學習筆記陣列筆記
- POJ 3415 Common Substrings(字尾陣列求重複字串)陣列字串
- 求二維陣列中最大子陣列的和陣列
- HDU 5769-Substring(字尾陣列-不相同的子串的個數)陣列
- HDU 4622 Reincarnation( 任意區間子串的長度, 字尾陣列+RMQ)陣列MQ
- BZOJ2882: 工藝(字尾陣列)陣列
- POJ 3581-Sequence(字尾陣列)陣列
- POJ 1743 Musical Theme(字尾陣列)陣列
- JavaScript 陣列排序 與 求最大值JavaScript陣列排序
- 獲取陣列中子串乘積的最大值陣列
- 求最大子陣列(貪心演算法)陣列演算法
- POJ 3415-Common Substrings(字尾陣列+單調棧-公共子串的長度)陣列
- ES6字串轉換為陣列字串陣列
- POJ 1159 Palindrome(字串變回文:LCS)字串
- 【Kmp求既是字首又是字尾的子串】POJ - 2752 Seek the Name, Seek the FameKMP
- Python找回文子串的方法Python
- leetcode------分割回文串LeetCode
- POJ1743 Musical Theme(字尾陣列 二分)陣列
- POJ2774Long Long Message(字尾陣列模板)陣列