太鼓达人
不知道有木有小伙伴,看了很多题解,还是不是很懂的,(比如说我)
我也不知道为什么这道题卡我很久,╮(╯▽╰)╭(可能是位运算的问题 下面会解释一下 )
下面是我突然顿悟(强行想通,没有证明的理解可能是错的 哈哈)
& 运算 是 两个数二进制 对齐后 上下都是 1 答案对应的位数 就是1 不然是0
例如:3 & 17 = 1
3= 00000011
17= 00010001
&= 00000001
la=(1<<(k-1))-1; 和 (x&la)<<1:
是为了让x(二进制)最高位去掉 在向左移一位。方便后面+0或1 (为了联通)
先看一下代码,后有一下提示
#include <bits/stdc++.h> #define ri register int using namespace std; const int M =10005; int k,m,n,vis[M],maxx,la,stk[M],top; void dfs(int x,int sum) // 一直搜索 找目标 { vis[x]=1; for(ri i=0;i<=1;i++) { int to=((x&la)<<1)+i; if(to==0&&sum==maxx) { for(ri i=1;i<=maxx;i++) if(i<=k) printf("0"); else printf("%d",stk[i]); exit(0); } if(!vis[to]) { stk[++top]=i; dfs(to,sum+1); top--; } } vis[x]=0; } int main(){ scanf("%d",&k);top=k; maxx=(1<<k); la=(1<<(k-1))-1; printf("%d ",maxx); dfs(0,1); }
为什么 top=k,首先前k位一定是0,没有错吧,但是这个代码vis[000] 不存在的 (vis[0] 就标记了)
说以我们要从后面开始计数, 其实这个dfs是从1开始的(以k=3为例) 他的dfs序列是10111000(啰嗦一下最后一个0 是 (100&la)<<1 +0 来的)我们就是把000放后面了,输出时就先输出000;
从来没有为一道题出博客,卡我琢磨久,不写不舒服啊