bzoj 3033: 太鼓达人 [欧拉回路]

3033: 太鼓达人

题意:长m的01环,每个长k的子串都是不同的01串。给出k,求最大的M以及字典序最小的方案。


(M=2^k)

可以把k-1位01串看成点,k位01串就是边,满足欧拉回路的条件。

然后求字典序最小的欧拉回路就行了,优先走字典序小的边

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define fir first
#define sec second
const int N = (1<<11)+5, inf = 1e9+5;
inline int read() {
    char c=getchar(); int x=0,f=1;
    while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
    return x*f;
}

int m, k, mark[N], st[N], top, c;
void dfs(int s) {
	for(int i=0; i<2; i++) {
		int t = (s<<1) | i;
		if(mark[t]) continue;
		mark[t] = 1;
		dfs(t & c);
		st[++top] = t;
	}
}
int main() {
	k = read(); m = 1<<k;
	printf("%d ", m);
	for(int i=0; i<k-1; i++) c |= (1<<i);
	dfs(0);
	for(int i=0; i<k; i++) printf("%d", st[top] & (1<<i)); 
	top--;
	while(top >= k) printf("%d", st[top--] & 1);
}
原文地址:https://www.cnblogs.com/candy99/p/6858615.html