题目:http://acm.hdu.edu.cn/showproblem.php?pid=2894
3
8 00010111
/* 看到k的值不大,猜想和枚举搜索等相关 */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=2100; //2^11=2048 int k,num; char str[maxn],s[15]; bool tag[maxn]; int get(){ int ans=0,temp; if(s[k-1]=='1') ans+=1; temp=1; for(int i=k-2;i>=0;i--){ temp*=2; if(s[i]=='1') ans+=temp; } return ans; } bool flag; void dfs(char x,int top){ strncpy(s,str+top-k+1,k); s[k-1]=x; int temp=get(); if(!tag[temp]){ tag[temp]=1; str[top]=x; if(top==num-1){ flag=1; return ; } //cout<<temp<<" "<<s<<" "<<str<<endl; dfs('0',top+1); dfs('1',top+1); if(flag) return ; tag[temp]=0; str[top]=0; } } int main() { while(cin>>k){ num=(1<<k); memset(tag,0,sizeof(tag)); memset(s,0,sizeof(s)); memset(str,0,sizeof(str)); for(int i=0;i<k;i++){ s[i]='0'; str[i]='0'; } tag[0]=1; flag=0; dfs('1',k); printf("%d %s\n",num,str); } return 0; }
/* 圆环上一定有2^n个小段,把小段的两个端点看做各自一点,那么就有2^n个点。 这些点刚好形成一个欧拉回路。怎样由一个点寻找下一个点呢?设当前点是k, 那么和它各二进制位差异最小的相邻点就是(k<<1)&((1<<n)-1)或者(k<<1)&((1<<n)-1)+1. 0 000; 1 001; 2 010; 4 100; 5 101; 3 011; 6 110; 7 111. 如果在递归之前把01放进sta中,正序输出的结构应该是01001101。应该在dfs终止了 (一条路走不通了)才放进01信息(那样最先进入的一定是111……),最后逆序输出 */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=2100; bool vis[N]; int sta[N],top,k,num; void dfs(int x){ int q1=(x<<1)&((1<<k)-1),q2=q1+1; if(!vis[q1]){ vis[q1]=1; //sta[++top]=0; dfs(q1); sta[++top]=0; } if(!vis[q2]){ //两个都是if 不是if,else if的关系 vis[q2]=1; //sta[++top]=1; dfs(q2); sta[++top]=1; } } int main() { while(cin>>k){ num=(1<<k); top=0; memset(vis,0,sizeof(vis)); dfs(0); printf("%d ",num); for(int i=1;i<k;i++)printf("0"); for(int i=top;i>=k;i--) printf("%d",sta[i]); puts(""); //for(int i=1;i<=top;i++) printf("%d",sta[i]); //printf("%d\n",sta[top-1]); } return 0; }