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);
}
posted @ 2017-05-15 21:43 Candy? 阅读(...) 评论(...) 编辑 收藏