題意:
給定一個只有a和b的字符串,輸出它第 K 個半迴文子串
半迴文串的定義是,所有奇數位置都是迴文的
給出半迴文串定義是:對於隨意i<=|s|/2 有s[i] = s[len-i+1]
其中字符串長度不超過5000 ,保證有解
思考:
數據量是5000 時間給了1500ms
O(n^2)的算法可行
簡單暴力的方法就是n^2 dp 出(i,j)的子串是不是半迴文串,再把全部子串插入字典樹。在dfs遍歷出第k小的串
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5005;
const int mod=1e9+7;
int dp[maxn][maxn];
char s[maxn];
int w;
struct Trie
{
Trie *child[2];
int num;
Trie()
{
memset(child,0,sizeof(child));
num=0;
}
}trie[maxn*maxn];
int n,k;
int nodeCount=0;
Trie *root,*cur;
Trie *createnode()
{
return &trie[nodeCount++];
}
void insertnode(int p)
{
cur=root;
for(int i=p;i<=n;i++)
{
int val=s[i]-'a';
if(cur->child[val]==NULL) cur->child[val]=createnode();
cur=cur->child[val];
cur->num=cur->num+dp[p][i];
}
}
vector<char>ans;
bool dfs(Trie *cur,int &k)
{
if(k<=0)
return 1;
if(cur->child[0]!=0)
{
ans.push_back('a');
if(cur->child[0]->num!=0)
k=k-(cur->child[0]->num);
if(dfs(cur->child[0],k))
return 1;
ans.pop_back();
}
if(cur->child[1]!=0)
{
ans.push_back('b');
if(cur->child[1]->num!=0)
k=k-cur->child[1]->num;
if(dfs(cur->child[1],k))
return 1;
ans.pop_back();
}
return 0;
}
int main()
{
scanf("%s%d",s+1,&k);
n=strlen(s+1);
for(int i=0;i<=n+3;i++)
for(int j=0;j<=i;j++)
dp[i][j]=1;
for(int len=2;len<=n;len++)
for(int l=1;l+len-1<=n;l++)
{
int r=l+len-1;
if(s[l]==s[r]&&dp[l+2][r-2]!=0)
dp[l][r]=1;
else
dp[l][r]=0;
}
root=createnode();
for(int i=1;i<=n;i++)
insertnode(i);
dfs(root,k);
for(__typeof((ans).begin())i=ans.begin();i!=ans.end();i++)
printf("%c",*i);
printf("\n");
return 0;
}
題目:
Tomorrow Ann takes the hardest exam of programming where she should get an excellent mark.
On the last theoretical class the teacher introduced the notion of a half-palindrome.
String t is a half-palindrome, if for all the odd positions i () the following condition is held: ti = t|t| - i + 1, where |t| is the length of string t if positions are indexed from 1. For example, strings "abaa", "a", "bb", "abbbaa" are half-palindromes and strings "ab", "bba" and "aaabaa" are not.
Ann knows that on the exam she will get string s, consisting only of letters a and b, and number k. To get an excellent mark she has to find the k-th in the lexicographical order string among all substrings of s that are half-palyndromes. Note that each substring in this order is considered as many times as many times it occurs in s.
The teachers guarantees that the given number kdoesn't exceed the number of substrings of the given string that are half-palindromes.
Can you cope with this problem?
Input
The first line of the input contains string s (1 ≤ |s| ≤ 5000), consisting only of characters 'a' and 'b', where |s| is the length of string s.
The second line contains a positive integer k — the lexicographical number of the requested string among all the half-palindrome substrings of the given string s. The strings are numbered starting from one.
It is guaranteed that number k doesn't exceed the number of substrings of the given string that are half-palindromes.
Output
Print a substring of the given string that is the k-th in the lexicographical order of all substrings of the given string that are half-palindromes.
Examples
Input
abbabaab 7
Output
abaa
Input
aaaaa 10
Output
aaa
Input
bbaabb 13
Output
bbaabb
Note
By definition, string a = a1a2... an is lexicographically less than string b = b1b2... bm, if either a is a prefix of b and doesn't coincide with b, or there exists such i, that a1 = b1, a2 = b2, ... ai - 1 = bi - 1, ai < bi.
In the first sample half-palindrome substrings are the following strings — a, a, a, a, aa, aba, abaa, abba, abbabaa, b, b, b, b, baab, bab, bb, bbab, bbabaab (the list is given in the lexicographical order).