Description
Input
Output
Sample Input
2 0 2 1 2 2 2 3 0 0
Sample Output
0 1 3 2
题意:让你找个字典序最小的序列使得排成环旋转后取n个,最后可以取到[0-2^n)的所有数。
思路:欧拉回路的应用,首先为了找最短,所有我们希望这个数的后n-1位和下一个数的前n-1位是相同的,只有他们的头和尾不一样,所以我们有每添加一位就可以构成一个新的数,那么这两个数就能通过这位来连接,我们可以先枚举出所有的节点,然后对应产生边,我们最后要跑完所有的边且回到原点,而这就是欧拉回路了
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <vector> using namespace std; const int maxn = 1<<16; struct Edge { int v, via; int vis; }; vector<Edge> ve[maxn]; int path[maxn<<1]; int n, k, cnt; void init() { for (int i = 0; i < maxn; i++) ve[i].clear(); } void dfs(int cur) { for (int i = 0; i < ve[cur].size(); i++) if (!ve[cur][i].vis) { ve[cur][i].vis = 1; dfs(ve[cur][i].v); path[++cnt] = ve[cur][i].via + '0'; } return; } int main() { while (scanf("%d%d", &n, &k) != EOF && n+k) { int len = n; n = (1<<(n-1)) - 1; init(); Edge tmp; for (int i = 0; i <= n; i++) { int t = (i<<1) - ((i&(1<<(len-2)))<<1); tmp.v = t; tmp.via = 0; tmp.vis = 0; ve[i].push_back(tmp); t += 1; tmp.v = t; tmp.via = 1; tmp.vis = 0; ve[i].push_back(tmp); } cnt = -1; dfs(n); path[++cnt] = '\0'; reverse(path, path+cnt); int ans = 0; for (int i = k, j = 1; j <= len; j++, i++) ans = (ans<<1) + (path[i%cnt]-'0'); printf("%d\n", ans); } return 0; }
POJ - 1392 Ouroboros Snake (欧拉回路的应用),布布扣,bubuko.com
POJ - 1392 Ouroboros Snake (欧拉回路的应用)
原文:http://blog.csdn.net/u011345136/article/details/38454177