bzoj3033: 太鼓达人 欧拉路径

题目链接

bzoj3033: 太鼓达人

题解

对于k-1位点,k位二进制位边,将点的转移连起来
每个点的入度和出度相等并且全部是偶点
只需要在这个图中找字典序最小的欧拉回路
可以贪心地找字典序较小的边,然后实在不行了就回溯

代码

#include<cstdio> 
#include<cstring> 
#include<algorithm> 
#define rep(p,x,k) for(int p = x;p <= k;++ p) 
#define per(p,x,k) for(int p = x;p >= k;-- p) 
#define gc getchar()
#define pc putchar 
#define LL long long  
inline LL read() {
    LL x = 0,f = 1; 
    char c = gc; 
    while(c < '0' || c > '9') c = gc; 
    while(c <= '9' && c >= '0') x = x * 10 + c -'0',c = gc; 
    return x ; 
} 
void print(LL x) { 
    if(x < 0) { 
        pc('-'); 
        x = -x; 
    } 
    if(x >= 10) print(x / 10); 
    pc(x % 10 + '0'); 
} 
int m,l; 
bool vis[100007]; 
int ans[100007]; 
bool dfs(int s,int k) { 
    if(vis[s]) return 0; 
    if(k == l) return 1;  
    vis[s] = 1; 
    ans[k] = s & 1; 
    if (dfs((s << 1) & (l - 1), k + 1) )return 1; 
    if (dfs((s << 1 | 1) & (l - 1),k + 1)) return 1; 
    vis[s] = 0; 
    return 0; 
} 
int main() { 
    m = read(); 
    print(l = 1 << m); 
    pc(' '); 
    dfs(0,1); 
    for(int i = 1;i < m;++ i) pc('0'); 
    for(int i = 1;i <= l - m + 1;++ i) pc(ans[i] + '0');        
    return 0; 
} 
posted @ 2018-10-16 21:25  zzzzx  阅读(249)  评论(0编辑  收藏  举报