無向圖的歐拉回路:
1.圖連通;
2.圖所有點度數均爲偶數;
//歐拉路徑要求起點和終點度數爲奇數;
有向圖的歐拉回路:
1.圖連通;
2.圖所有點入度等於出度;
//歐拉路徑要求起點入度=出度-1,終點入度=出度+1;
歐拉回路:通過圖中每條邊一次且僅一次,並且過每一頂點的迴路。
關鍵詞是:每條邊僅經過一次。
也就是說如果一道題建圖後,要求一條迴路(路徑),每條邊經過且僅經過一次。
回到這道題:
顯然長度爲2^k。
網上看到的題解只有這個講的是正確的。
即:把2^k個數當成邊,設出2^(k-1)個點。
然後再跑歐拉回路。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
int sk[M],sp[M],vs[M],nm[M];
int ans[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int k;
cin>>k;
//以k=3爲例
int n=1<<(k-1);//4個點:00 01 10 11
int m=1<<k;//8條邊:000 001 010 100 110 011 101 111
int tp=(1<<(k-1))-1;
int t=0,top=0;
sk[++top]=0;
while(top)
{
int x=sk[top];
int v=(x<<1)&tp;// abc -> bc0
int w=x<<1;
if(vs[w])
{
v++;w++;
if(vs[w])
{
ans[++t]=sp[top];
top--;
}
else sk[++top]=v,sp[top]=1,vs[w]=1;
}
else sk[++top]=v,sp[top]=0,vs[w]=1;
}
cout<<m<<" ";
for(int i=1;i<k;i++)cout<<0;
for(int i=t-1;i>=k;i--)cout<<ans[i];
cout<<endl;
return 0;
}