You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
7.0 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
/* 举栗子:以下面的小方框个数=3为例其实是模拟了4个点8条边也就是(00,01,10,11)->通过尾部加0或加1->构建边->(000,001,010,011,100,101,110,111)-> 去掉头部第1个->(00,01,10,11)
4=2^2=2(3-1),8=2^3,广n,2^(n-1),2^n=[0000...0,1111...1]
1<=N<=15,N=16,NM=N*2NM1<<16,
*/
const int N = 1 << 16, M = N;
int len;
int res[N], rl; // 路径记录器
int st[N]; // 某条边是不是出现过了
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
// dfs求有向图欧拉回路
void dfs(int u) {
for (int i = h[u]; ~i; i = h[u]) {
h[u] = ne[i]; // 套路式删边,优化性能
int id = w[i];
if (st[id]) continue; // 如果id这条边访问过了那么不需要重复访问
st[id] = 1; // 标记i号边已访问过
dfs(e[i]); // 递归搜索v号点
// cout << "u=" << u << ",v=" << v << ","
// << "w[i]=" << w[i] << endl;
res[++rl] = id; // 以边的形式记录欧拉路径,i号索引的这条边它的真实边号为w[i]
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("HihoCoder1182.in", "r", stdin);
#endif
int n;
scanf("%d", &n);
memset(h, -1, sizeof h);
/*
len
102100,101
(1)10->0->-> 100 ->?
(2)10->1->-> 101 ->?
00011
410001
4 1<< (n-1)!
len= 1<<(n-1) ID
*/
len = 1 << (n - 1);
// len的第二层含义如果点号从0开始计数那么最大的点号也是 1<<(n-1),以n=3为例四个点就是(0,1,2,3),最大点号 3= (1<<(3-1)) -1
for (int a = 0; a < len; a++) {
int c = a << 1 | 1; // 点号左移一位尾部添1以10为例就是变成 100+1=101这是一个点到边的变换过程,num是指边号对应的十进制数比如101=5
int b = c % len; // 再模一下我们精心准备的len,就可以把头部第1位裁掉得到目标节点号
add(a, b, c); // 从a点出发到b点去通过一条边号为num的边.我们把链式前向星魔改了一下,把边权重定义为边的边号
c = a << 1; // 点号左移一位尾部添0以10为例就是变成 100这是一个点到边的变换过程,num是指边号对应的十进制数比如100=4
b = c % len; // 再模一下我们精心准备的len,就可以把头部第1位裁掉得到目标节点号
add(a, b, c); // 从a点出发到b点去通过一条边号为num的边.我们把链式前向星魔改了一下,把边权重定义为边的边号
// 上面这段,配置题解中的图进行理解效果更佳!
}
/*
Q:,西
=2=2
,,2
0,
0dfs(v)
dfs(v)
*/
dfs(0);
/* 题目要求:输出 1个长度为2^n的01串表示一种符合要求的分布方案
00010111(3)
111001
221011
331111
4401110
5511101
6601010
7700100
8800000
dfs
u=2,v=0,w[i]=4 =(100)
u=3,v=2,w[i]=6 =(110)
u=3,v=3,w[i]=7 =(111)
u=1,v=3,w[i]=3 =(011)
u=2,v=1,w[i]=5 =(101)
u=1,v=2,w[i]=2 =(010)
u=0,v=1,w[i]=1 =(001)
u=0,v=0,w[i]=0 =(000)
00010111
!
Q
000->->0
001->->0
010->->0
101->->1
011->->0
111->->1
110->->1
100->->1
Q:
res[i]/lenlen=4,
*/
for (int i = rl; i; i--) printf("%d", res[i] / len);
return 0;
}