题目链接

fleury+旋转鼓轮问题

如果不是环状的,那么存储的字符串长度就是 $2^n$+n-1 个,否则字符串长度是 $2^n$+1

用fleury打表求出15种情况的路径

要注意栈存储的数据的正逆序,取数的时候别弄错了

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int Maxn = 1e5+10;

struct Node {
	int top, node[Maxn];
} S;

bool vis[Maxn*10];
int str[20][Maxn];

void dfs(int x, int n) {
	for(int i = 0; i < 2; ++i) {
		int tmp = (x<<1)|i;
		if(vis[tmp]) continue;
		vis[tmp] = true;
		tmp &= ~(1<<(n-1));
		S.node[++S.top] = tmp;
		dfs(tmp, n);
		break;
	}
}

void fleury(int n) {
	memset(vis, false, sizeof(vis));
	vis[0] = true;
	S.top = 0; S.node[0] = 0;
	int cnt = 0;
	while(S.top >= 0) {
		bool ok = false;
		for(int j = 0; j < 2; ++j) {
			int tmp = S.node[S.top];
			if(vis[(tmp<<1)|j]) continue;
			ok = true; break;
		}
		if(!ok) {
			S.top--;
			str[n][cnt++] = ((S.node[S.top+1])>>(n-2)&1);
		} else {
			dfs(S.node[S.top], n);
		}
	}
	str[n][cnt++] = 0;
}

int main(void)
{
	for(int i = 1; i <= 15; ++i) {
		fleury(i);
	}
	int n, k;
	while(scanf("%d%d", &n, &k) != EOF) {
		if(!n && !k) break;
		if(n == 1 && k == 0) printf("0\n");
		else if(n == 1 && k == 1) printf("1\n");
		else {
			int ans = 0, cnt = n-1;
			for(int i = (1<<n)-k; i > (1<<n)-k-n; --i) {
				int num = str[n][i];
				ans |= (num<<(cnt--));
			}
			printf("%d\n", ans);
		} 
	}
	return 0;
 }