51nod 1416半回文

来源:互联网 发布:淘宝白菜群对商家 编辑:程序博客网 时间:2024/06/05 22:52
题目来源:
51nod 1416半回文


题目描述:
一个字符串t是半回文的条件是,对于所有的奇数i(1≤i≤|t|+12),ti = t|t| − i + 1 始终成立,|t|表示字符串t的长度。下标从1开始。例如"abaa", "a", "bb", "abbbaa"都是半回文,而"ab", "bba"和"aaabaa"则不是。
现在有一个字符串s,只由小写字母a,b构成,还有一个数字k。现在要求找出s的半回文子串中字典序排在第k位的串,字符串可以是一样,只要所在的位置不同就是不一样的串。
样例解释:
这个样例中半回文子串是 a, a, a, a, aa, aba, abaa, abba, abbabaa, b, b, b, b, baab,bab, bb, bbab, bbabaab (按照字典序排序).


Input
单组测试数据。
第一行有一个字符串s(1 ≤ |s| ≤ 5000),只包含'a' 和 'b',|s|表示s的长度。
第二行有一个正整数k。k不超过s子串中是半回文串的总数目。
Output
输出排在第k位的半回文子串。


示例
Input
abbabaab
7
Output
abaa


基准时间限制:1 秒 空间限制:262144 KB 


题解:先将整个序列预处理了一下,dp处理该串,标记所有半回文串


题目分类:
字典树 动态规划


代码:

//zcc#include<bits/stdc++.h>using namespace std;const int MAXN = 5e3 + 5;const int MAXM = 2;char s[MAXN];int k,n,l,r;int vis[MAXN];bool dp[MAXN][MAXN];string ans;struct Tree{    int val;    Tree *next[MAXM];    Tree()    {        val = 0;        memset(next, 0, sizeof next);    }} *tree_head;void init(){    tree_head = new Tree();    n = (int)strlen(s);    memset(dp, false, sizeof dp);    for (int i = n - 1; i >= 0; --i)    {        dp[i][i] = true;        vis[i] = i;        for (int j = i + 1; j < n; ++j)        {            if (s[i] == s[j])            {                if (i + 2 >= j - 2)                {                    dp[i][j] = true;                }                else                {                    dp[i][j] = dp[i + 2][j - 2];                }            }            if (dp[i][j])            {                vis[i] = j;            }        }    }}void insert_tree(Tree *ptemp, char *s){    if (*s == '\0')    {        return;    }    if (r > vis[l])    {        return;    }    int c = *s - 'a';    if (ptemp->next[c] == NULL)    {        ptemp->next[c] = new Tree();    }    if (dp[l][r])    {        ptemp->next[c]->val++;    }    r++;    insert_tree(ptemp->next[c], s + 1);}void dfs(Tree *ptemp){    string temp = ans;    if(k > 0 && ptemp->next[0])    {        k -= ptemp->next[0]->val;        ans = ans + 'a';        dfs(ptemp->next[0]);    }    if(k > 0 && ptemp->next[1])    {        ans = temp;        k -= ptemp->next[1]->val;        ans = ans + 'b';        dfs(ptemp->next[1]);    }}void solve(){    scanf("%s %d",s, &k);    init();    for (int i = 0; i < n; ++i)    {        l = r = i;        insert_tree(tree_head, s + i);    }    dfs(tree_head);    cout << ans << endl;}int main(){    solve();    return 0;}



原创粉丝点击