代码很短 但看别人的blog看了很久 才理解
第一问的答案毫无疑问是2^n
第二问的答案长度肯定是2^n 因为要求前n个必然是0
原问题是要求能够表示出0-(2^n-1)的数 每个数只能出现一次 一圈是一个循环 每条边也只能经过一次 就是求一个欧拉回路
从u向to1=(u<<1)&((1<<n)-1)和to2=to1+1分别连一条边 这样画个图就能看出来每个点的入度出度都是2
其他解释都在下面了
#include<cstdio>
#include<cstring>
using namespace std;
int p,d[1<<15],n;
bool vis[1<<15];
void dfs(int u)
{
int to1=(u<<1)&((1<<n)-1);//to1 to2就是去掉二进制数的首位然后在末位分别加上0和1
int to2=to1+1;//也就是模拟在k个接地部分旋转的情况 旋转一格 首位消失 添上末位 末位是0或者是1
if(!vis[to1])//因为不能重复出现所以要进行vis标记
{
vis[to1]=true;
dfs(to1);
d[++p]=0;
}
if(!vis[to2])//先搜0的之前的0无法达成的话 在搜1 这样就能实现字典序最小
{//因为是dfs的关系 所以采用栈结构(等下逆序输出)
vis[to2]=true;
dfs(to2);
d[++p]=1;
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(vis,0,sizeof(vis));
p=0;
dfs(0);//深搜
printf("%d ",1<<n);
printf("%d\n",p);
for(int i=1;i<n;i++) printf("0");//输出前导0
for(int i=p;i>=n;i--) printf("%d",d[i]);//逆序输出栈中的数
printf("\n");
}
return 0;
}