题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3033
考虑那 (1<<k) 个数,要形成答案,必然是相邻两个数间有 k-1 个重叠位置,也就是两个有 k-1 位前后对应相同的数之间可以连边转移;
发现这张图里每个点一定有两个入度、两个出度,也就是形成一张欧拉图;
所以暴搜时间有保证,暴搜即可;
对欧拉图还是太不熟悉了...暴搜也写不出来了...有种无力感...
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int const maxn=(1<<11)+5;//+5!!! int k,m,ans[maxn],num,top,lst[maxn]; bool fl,vis[maxn]; void find(int y,int x) { num=0; while(y!=x)ans[++num]=y,y=lst[y]; ans[++num]=x; } void dfs(int x) { vis[x]=1; top++; if(top==(1<<k)){find(x,0); fl=1; return;} for(int i=0;i<=1&&!fl;i++) { int y=((x&((1<<(k-1))-1))<<1|i); if(vis[y])continue; lst[y]=x; dfs(y); } vis[x]=0; top--; } int main() { scanf("%d",&k); // m=(1<<k);//比下面慢 // printf("%d ",m); dfs(0); printf("%d ",num); for(int i=num;i;i--)printf("%d",(ans[i]>>(k-1))); return 0; }