51nod 1464 半回文(字典树+DFS+预处理)
来源:互联网 发布:淘宝老顾客互换资源 编辑:程序博客网 时间:2024/06/10 16:51
1464 半回文
题目来源: CodeForces
基准时间限制:1 秒 空间限制:262144 KB 分值: 40 难度:4级算法题
收藏
关注
一个字符串t是半回文的条件是,对于所有的奇数
现在有一个字符串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示例
abbabaab7
Output示例
abaa
System Message (题目提供者)
Visual C++的运行时限为:1000 ms ,空间限制为:262144 KB 示例及语言说明请按这里
允许其他 AC 的用户查看此代码,分享代码才能查看别人的代码并有机会获得勋章
题解:假如暴力找出所有子串并判断是否为半回文串,然后按照字典序排序的话是活在梦里,
然而怎么避免活在梦里呢,我们可以考虑字典树,将所有的回文子串加入字典树然后查询。
这样的话避免了排序的复杂度,但是还是够呛,还能怎么优化呢。对于每一个子串,我们可以
通过预处理找到所有合法的子串,并开一个vis数组表示当前位置能延伸到的最远的位置所能构成的
合法子串,这样的话时间复杂度便大大降低了。。。然后dfs找就好了。。(记得要按顺序)
#include<set> #include<map> #include<stack> #include<queue> #include<vector> #include<string> #include<math.h> #include<time.h> #include<stdio.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<algorithm> #include<functional> using namespace std;typedef long long ll;#define inf 1000000000 #define mod 1000000007 #define maxn 6005 #define PI 3.1415926 #define lowbit(x) (x&-x) #define eps 1e-9char s[maxn * 1000];string ans;int dp[maxn][maxn], k, vis[maxn];int siz, a[maxn * 1000][2], cnt[maxn * 1000][2];void insert(int st) {int i, now = 0, len = strlen(s);for (i = st;i <= vis[st];i++){int v = s[i] - 'a';if (a[now][v] == 0)a[now][v] = ++siz;if (dp[st][i])cnt[now][v]++;now = a[now][v];}}void dfs(int x){string tmp = ans;if (k > 0 && a[x][0]){k -= cnt[x][0];ans = ans + 'a';dfs(a[x][0]);}if (k > 0 && a[x][1]){ans = tmp;k -= cnt[x][1];ans = ans + 'b';dfs(a[x][1]);}}int main(void){int i, j;scanf("%s", s);scanf("%d", &k);int len = strlen(s);for (i = len-1;i >= 0;i--){dp[i][i] = 1;vis[i] = i;for (j = i + 1;j < len;j++){if (s[i] == s[j]){if (i + 2 >= j - 2)dp[i][j] = 1;elsedp[i][j] = dp[i + 2][j - 2];}if (dp[i][j])vis[i] = j;}}for (i = 0;i < len;i++)insert(i);dfs(0);cout << ans << endl;return 0;}
阅读全文
1 0
- 51nod 1464 半回文(字典树+DFS+预处理)
- 51nod 1523 非回文(DFS)
- 51Nod-1464-半回文
- 51nod 1464 半回文
- 51nod 1464 半回文(dp,Trie)
- 51nod 1416半回文
- 51nod 40 序列分解 暴力dfs or 折半+字典树
- 51nod 1092 回文字符串 (添加几个变成回文)
- 51nod 1092 回文字符串 (LCS_DP)
- 【51Nod】1092 - 回文字符串(LCS)
- 51nod 1092 回文字符串(LCS)
- hdu1298(字典树+dfs)
- 51nod round3# 序列分解(折半枚举+字典树)
- 51Nod 1681(DFS序+主席树)
- 51nod 1405 树的距离之和(DFS)
- 51nod 1295 XOR key(字典树)
- 51nod 1526 分配笔名(字典树)
- 【51nod 扔盘子】+ 预处理
- 配置Android Studio的缓存文件路径(释放你的C盘)
- 数据结构-优先队列
- Apache2.4.9部署服务能让局域网及外网可以访问-摘记
- Leetcode 547. Friend Circles
- kuangbin 数论基础 C题
- 51nod 1464 半回文(字典树+DFS+预处理)
- Linux命令小结
- 关于Java方法分页后数据重复的一种解答
- Android蓝牙学习——搜索、配对、传文件(附源码)
- spark-streaming-kafka-0-8 和 0-10的使用区别
- 错误 Error: Expected resource of type id [ResourceTyp]
- Android开发 之 ColorFilter详解
- Linux下MySQL 安装配置
- 嵌入式编程中,你应该知道的定点化知识