hdu 4850 Wow! Such String!(欧拉回路)
2014-07-08 20:02
381 查看
题目链接:hdu 4850 Wow! Such String!
题目大意:给定一个n,要求输出一个长度为n的字符串,并且不会有长度大于等于4的重复的子串,不能得到输出impossible。
解题思路:这题有一个误导性的地方,500000,其实是构造不到那么长的,我们考虑所有不相同并且长度为4的串,一共有s=264个,那么我们假设有一个很长的串,满足不会有长度大于等于4的重复的子串,那么以0,1,2,3...的位置为起始,长度为4的子串一定都是s中的某一个串,因为不重复,所以肯定只有264个位置做为起始点,加上最末尾的3个字符,一共是264+3的长度是可以构造条件串的。
构造方法其实就是欧拉回路,以长度为3的串为节点,一共有263个节点,每个节点出度为26,入度为26,最后构造出的串起始就是走过边的权值,要求每个节点刚好经过26次。我用的是贪心的方法,每次移动的下一个节点,一定是当前能移动到节点的中经过最少次数的节点,这样做去保证每个节点都能刚好走26次。
注意:因为一开始是aaa的节点,所以对于每个节点来说,权值为a的边要放在最后没路走的时候才去考虑,因为对于该图来说是一个欧拉回路,也就是说最后要回答aaa这个点,如果过程中就对权值a的边进行考虑,那么可能在过程中就将aaa的点走过一次,那么最后路就会被封死。所以一定要将回去的边留出来。
题目大意:给定一个n,要求输出一个长度为n的字符串,并且不会有长度大于等于4的重复的子串,不能得到输出impossible。
解题思路:这题有一个误导性的地方,500000,其实是构造不到那么长的,我们考虑所有不相同并且长度为4的串,一共有s=264个,那么我们假设有一个很长的串,满足不会有长度大于等于4的重复的子串,那么以0,1,2,3...的位置为起始,长度为4的子串一定都是s中的某一个串,因为不重复,所以肯定只有264个位置做为起始点,加上最末尾的3个字符,一共是264+3的长度是可以构造条件串的。
构造方法其实就是欧拉回路,以长度为3的串为节点,一共有263个节点,每个节点出度为26,入度为26,最后构造出的串起始就是走过边的权值,要求每个节点刚好经过26次。我用的是贪心的方法,每次移动的下一个节点,一定是当前能移动到节点的中经过最少次数的节点,这样做去保证每个节点都能刚好走26次。
注意:因为一开始是aaa的节点,所以对于每个节点来说,权值为a的边要放在最后没路走的时候才去考虑,因为对于该图来说是一个欧拉回路,也就是说最后要回答aaa这个点,如果过程中就对权值a的边进行考虑,那么可能在过程中就将aaa的点走过一次,那么最后路就会被封死。所以一定要将回去的边留出来。
#include <cstdio> #include <cstring> #include <set> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 26*26*26; const int mod = 26 * 26; const int maxl = 500005; int maxlen; int v[maxn+5][30], c[maxn+5]; char s[maxl]; inline int get_next (int u, int k) { return (u % mod) * 26 + k; } int find_next (int u) { int x = 0, ans = -1; for (int i = 1; i < 26; i++) { if (v[u][i]) continue; int tmp = get_next(u, i); if (ans == -1 || c[tmp] < c[ans]) { ans = tmp; x = i; } } return x; } void init () { maxlen = maxn * 26 + 3; int mv, u = 0; memset(v, 0, sizeof(v)); for (mv = 0; mv < 3; mv++) s[mv] = 'a'; while (true) { int x = find_next(u); int next = get_next(u, x); if (c[next] == 26) break; c[next]++; s[mv++] = x + 'a'; v[u][x] = 1; u = next; } /* for (int i = 0; i < maxn; i++) { bool flag = false;; for (int j = 0; j < 26; j++) if (v[i][j] == 0) flag = true; if (flag) printf("%d\n", i); } printf("%d %d\n", mv, maxlen); */ } int main () { int n; init(); while (scanf("%d", &n) == 1) { if (n <= maxlen) { for (int i = 0; i < n; i++) printf("%c", s[i]); printf("\n"); } else printf("Impossible\n"); } return 0; }
相关文章推荐
- hdu 4850 Wow! Such String! 构造 欧拉回路
- HDU 4850 Wow! Such String! 欧拉回路
- HDU - 4850 Wow! Such String! 构造(字符串上的欧拉回路)
- hdu 4850 Wow! Such String! 欧拉回路
- hdu 4850 Wow! Such String! 构造 欧拉回路
- HDU 4850 2014西安邀请赛 D题 Wow! Such String!
- 【HDU】4850 Wow! Such String! 提出猜想题
- hdu 4850 Wow! Such String! 2014西安全国邀请赛
- HDU - 4850~Wow! Such String!(dp)
- HDU 4850 Wow! Such String!(欧拉道路)
- hdu 4850 Wow! Such String! 构造 或 欧拉路径并改写成非递归版本
- HDU 4850 Wow! Such String!
- HDU 4850 Wow! Such String! 欧拉路径
- HDU 4850 2014西安邀请赛 D题 Wow! Such String!
- hdu 4850 Wow! Such String!(字符串处理,yy)
- 构造字符串 之 hdu 4850 Wow! Such String!
- HDU 4850 Wow! Such String!(欧拉道路)
- HDU-4850 Wow! Such String! (构造)
- 【HDU】4850 Wow! Such String! 提出猜想题 欧拉道路
- 构造字符串 之 hdu 4850 Wow! Such String!