1. 程式人生 > >HihoCoder1182 歐拉路(Fleury算法)

HihoCoder1182 歐拉路(Fleury算法)

分表 space ios name 連續 bsp fleury算法 com nbsp

描述

小Hi和小Ho破解了一道又一道難題,終於來到了最後一關。只要打開眼前的寶箱就可以通關這個遊戲了。

寶箱被一種奇怪的機關鎖住:

技術分享圖片

這個機關是一個圓環,一共有2^N個區域,每個區域都可以改變顏色,在黑白兩種顏色之間切換。

小Ho控制主角在周圍探索了一下,果然又發現了一個紙片:

機關黑色的部分表示為1,白色的部分表示為0,逆時針連續N個區域表示一個二進制數。打開機關的條件是合理調整圓環黑白兩種顏色的分布,使得機關能夠表示0~2^N-1所有的數字。
我嘗試了很多次,終究沒有辦法打開,只得在此寫下機關破解之法。
	——By 無名的冒險者
	

小Ho:這什麽意思啊?

小Hi:我給你舉個例子,假如N=3,我們通過順時針轉動,可以使得正下方的3個區域表示為:

技術分享圖片

因為黑色表示為1,白色表示為0。則上面三個狀態分別對應了二進制(001),(010),(101)

每轉動一個區域,可以得到一個新的數字。一共可以轉動2^N次,也就是2^N個數字。我們要調整黑白區域的位置,使得這2^N個數字恰好是0~2^N-1

小Ho:我懂了。若N=2,則將環上的黑白色塊調整為"黑黑白白",對應了"1100"。依次是"11","10","00","01"四個數字,正好是0~3。那麽這個"黑黑白白"就可以打開機關了咯?

小Hi:我想應該是的。

小Ho:好像不是很難的樣子,我來試試!

輸入

第1行:1個正整數,N。1≤N≤15

輸出

第1行:1個長度為2^N的01串,表示一種符合要求的分布方案

樣例輸入

3

樣例輸出

00010111
  • 給這2^N個點建圖,若a->b要建邊,需滿足b刪第一位等於b刪最後一位,a>>1 == b & 2^(n-1)-1,但是這樣的話,就是要求一個方案使得每個點路過一次———>哈密頓回路,而哈密頓回路是NP問題,實現起來也麻煩。
  • 換個思路,我們想辦法把哈密頓轉化為歐拉。然後再用上一題的辦法解決。我們把點轉化為邊。
  • 輸出的時候,註意第一位是輸出全部,後面的輸出最後一位,而且最後那條回路邊不輸出。
#include <cstdio>
#include 
<cstdlib> #include <cstring> #include <iostream> #include <cmath> using namespace std; int used[100010],path[100010],n,m,cnt,tot=1; int Laxt[100010],Next[100010],To[100010]; void print_two(int n) { if(n) f(n>>1); else return; printf("%d",n%2); } void add(int u,int v) { Next[++tot]=Laxt[u]; Laxt[u]=tot; To[tot]=v; } void dfs(int u) { for(int i=Laxt[u];i;i=Next[i]){ if(!used[i]){ used[i]=1; dfs(To[i]); } } path[++cnt]=u; } int main() { int i,u,v,P; scanf("%d",&n); n=pow(2,n); for(i=0;i<n;i++){ add(i>>1,i&((n>>1)-1)); } dfs(1); print_two(path[1]); for(i=2;i<cnt;i++) printf("%d",path[i]&1); return 0; }

HihoCoder1182 歐拉路(Fleury算法)