BZOJ3033: 太鼓達人(歐拉回路)
Submit: 524 Solved: 400
[Submit][Status][Discuss]
Description
七夕祭上,Vani牽著cl的手,在明亮的燈光和歡樂的氣氛中愉快地穿行。這時,在前面忽然出現了一臺太鼓達人機臺,而在機臺前坐著的是剛剛被精英隊伍成員XLk、Poet_shy和lydrainbowcat拯救出來的的applepi。看到兩人對太鼓達人產生了興趣,applepi果斷閃人,於是cl拿起鼓棒準備挑戰。然而即使是在普通難度下,cl的路人本性也充分地暴露了出來。一曲終了,不但沒有過關,就連鼓都不靈了。Vani十分過意不去,決定幫助工作人員修鼓。
鼓的主要元件是M個圍成一圈的感測器。每個感測器都有開和關兩種工作狀態,分別用1和0表示。顯然,從不同的位置出發沿順時針方向連續檢查K個感測器可以得到M個長度為K的01串。Vani知道這M個01串應該是互不相同的。而且鼓的設計很精密,M會取到可能的最大值。現在Vani已經瞭解到了K的值,他希望你求出M的值,並給出字典序最小的感測器排布方案。
Input
一個整數K。
Output
一個整數M和一個二進位制串,由一個空格分隔。表示可能的最大的M,以及字典序最小的排布方案,字元0表示關,1表示開。你輸出的串的第一個字和最後一個字是相鄰的。
Sample Input
Sample Output
8 00010111HINT
得到的8個01串分別是000、001、010、101、011、111、110和100。注意前後是相鄰的。長度為3的二進位制串總共只有8種,所以M = 8一定是可能的最大值。
對於全部測試點,2≤K≤11。
思路;我記得以前看到過這樣的題,資料比較大的情況下,有個什麼演算法專門做這個的,當時一大篇,沒看懂,叫什麼我都忘了,估計是論文題。
首先答案是2^K,即每個數都可以納進去。 然後考慮字典序最小,我們可以把這2^K個數看成邊,方向是首位指向末位,這樣的話每個點的度數一定為偶數,所以存在歐拉回路,資料比較小,我們暴搜就ok了。
#include<bits/stdc++.h> using namespace std; const int maxn=100010; int vis[maxn],a[maxn],N; bool dfs(int pos,int now) { a[pos]=now&1; vis[now]=1; if(pos==(1<<N)) return true; int tmp=now; if(now&(1<<(N-1))) tmp-=(1<<(N-1)); if(!vis[tmp*2]){ if(dfs(pos+1,tmp*2)) return true; vis[tmp*2]=0; } if(!vis[tmp*2+1]){ if(dfs(pos+1,tmp*2+1)) return true; vis[tmp*2+1]=0; } return false; } int main() { scanf("%d",&N); printf("%d ",1<<N); dfs(N,0); for(int i=1;i<N;i++) putchar('0'); a[(1<<N)]=1; for(int i=N;i<=(1<<N);i++) printf("%d",a[i]); return 0; }