1. 程式人生 > >hihor 學習日記:hiho一下 第五十一週 (尤拉圖)

hihor 學習日記:hiho一下 第五十一週 (尤拉圖)

http://hihocoder.com/contest/hiho51/problem/1

思路:

可以把輪盤的轉換成成一張圖,圖由 2 N 1 2^{N -1}

個點, 2 N 2^{N} 條邊,因為數字的轉換是在後面N-1個數字後面加上1或0,所以點代表的就是後面N-1個數,邊代表形成的數字,‘
比如N=3時:
在這裡插入圖片描述
這樣就轉化成一個有向圖,那麼把邊全走一遍,並且每條邊只走一次,那麼就是找這個圖的歐拉回路,那麼這個圖存在不存在歐拉回路呢?
題目給出瞭解釋
在這裡插入圖片描述

額,那根據給的虛擬碼,寫出程式時,得出的結果是:
在這裡插入圖片描述
倒過來時
1 3 7 6 5 2 4 0
001 011 111 110 101 010 100 000
易見,可以拼接成一個01串

AC程式碼:

#include <bits/stdc++.h>

using namespace std;
#define LL long long
const int Mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const double eps = 0.00000001;
const int INF = 0x3f3f3f3f;

struct Edge{
    int v, nex, w;
}edge[
maxn << 1]; int tot, head[maxn]; int path_size = 0; int path[maxn], vis[maxn]; void init() { tot = 0; memset(head, -1, sizeof(head)); memset(vis, 0, sizeof(vis)); } void addEdge(int u, int v, int w) { edge[tot].v = v; edge[tot].w = w; edge[tot].nex = head[u]; head[u] = tot ++; } void DFS(int u) { for (int i = head[u]; i + 1; i = edge[i].nex) { int v = edge[i].v; if(!vis[i]) { vis[i] = 1; DFS(v); path[path_size ++] = i; } } } int main() { init(); int N; cin >> N; N --; for (int i = 0; i < (1 << N); i ++) { if(((i << 1) & (1 << N))) { addEdge(i, (i << 1) ^ (1 << N), ((i << 1) ^ (1 << N)) << 1); addEdge(i, (i << 1) ^ (1 << N) ^ 1, (i << 1) ^ 1); }else { addEdge(i, i << 1, i << 1); addEdge(i, i << 1 | 1, i << 1 | 1); } } DFS(0); for (int i = 0; i < path_size - 1; i ++) cout << (path[i] & 1); cout << path[-- path_size]; return 0; }