欧拉回路,转动鼓轮的应用。
DeBruijin
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 307 Accepted Submission(s): 195
Problem Description
旋转鼓的表面分成m块扇形,如图所示(m=8)。图中阴影区表示用导电材料制成,空白区用绝缘材料制成,终端a、b和c是3(k=3)处接地或不是接地分别用二进制信号0或1表示。因此,鼓的位置可用二进制信号表示。试问应如何选取这8个扇形的材料使每转过一个扇形都得到一个不同的二进制信号,即每转一周,能得到000到111的8个数。
那我们现在把旋转鼓的表面分成m块扇形,每一份记为0或1,使得任何相继的k个数的有序组(按同一方向)都不同,对固定的k,m最大可达到多少,并任意输出符合条件的一个这样的有序组。
![](https://i-blog.csdnimg.cn/blog_migrate/93f44453abc1ee1a88b9ad6773fb9ced.jpeg)
那我们现在把旋转鼓的表面分成m块扇形,每一份记为0或1,使得任何相继的k个数的有序组(按同一方向)都不同,对固定的k,m最大可达到多少,并任意输出符合条件的一个这样的有序组。
Input
每个case输入一个数k (2<=k<=11),表示图中所示的abc这样的接地线的数量。
Output
每个case输出m所能达到的最大值 ,并且输出字典序最小的一个符合条件的有序组,中间用空格隔开。Case间没有空行。有序组输出的格式为:00010111(k=3,只输出一个周期(0001011100010111……),并且首尾刚好是相接的)。
Sample Input
3
Sample Output
8 00010111
//转动鼓轮模型
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
#define MAXN 2<<17
struct node
{
int v,id,next;
}edge[MAXN];
int path[MAXN],top;
bool vis[MAXN];
int head[MAXN],en;
int n,k;
void add(int u,int v,int id)
{
edge[en].v=v;
edge[en].id=id;
edge[en].next=head[u];
head[u]=en++;
}
void dfs(int u)
{
for(int i=head[u];i!=-1;i=edge[i].next)
if(!vis[edge[i].id])
{
vis[edge[i].id]=1;
dfs(edge[i].v);
path[top++]=edge[i].id;
}
}
int main()
{
while(~scanf("%d",&n))
{
int cnt;
cnt=1<<n;
int len=1<<(n-1);
memset(head,-1,sizeof(head)),en=0;
for(int i=0;i<len;i++)
{
int id=i<<1|1;
int v=id%len;
add(i,v,id);
id=i<<1;
v=id%len;
add(i,v,id);
//字典序最小
}
memset(vis,0,sizeof(vis)),top=0;
dfs(0);
cout<<cnt<<" ";
for(int i=top-1;i>=0;i--)
printf("%d",path[i]/len);
cout<<endl;
}
return 0;
}