非递归dfs+欧拉回路+旋转鼓轮问题
用dfs输出欧拉回路的路径,因为节点较多,需要用非递归dfs根据旋转鼓轮问题建边,边数为 \(10^n\)
输出的字符串个数一定要是 \(10^n\) + n - 1 个, 否则会output limit
边数只有 \(10^n\) 条,多出来的n-1其实都是0,写在字符串的前面。
#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
using namespace std;
const int Maxn = 1e5+10;
struct Node {
int cur, child;
Node(int x, int y): cur(x), child(y) {
}
};
vector <pair<int, bool> > G[Maxn*10];
stack <Node> S;
char str[Maxn*10];
void dfs(int cur, int edge_cnt) {
S.push(Node(cur, 0));
while(!S.empty()) {
Node tmp = S.top();
int u = tmp.cur, bg = tmp.child;
bool ok = false;
for(int i = bg; i < G[u].size(); ++i) {
if(G[u][i].second) continue;
ok = true;
edge_cnt--;
G[u][i].second = true;
tmp.cur = G[u][i].first; tmp.child = 0;
S.top().child = i;
S.push(tmp); break;
}
if(edge_cnt == 0) break;
if(!ok) {
S.pop();
tmp = S.top();
G[tmp.cur][tmp.child].second = false;
edge_cnt++;
S.top().child++;
}
}
}
int main(void)
{
int n;
while(scanf("%d", &n) != EOF) {
if(n == 0) break;
if(n == 1) {
printf("0123456789\n"); continue;
}
int limt = 1, edge_cnt = 0;
n--;
for(int i = 0; i < n; ++i) limt *= 10;
for(int i = 0; i < limt; ++i) G[i].clear();
for(int i = 0; i < limt; ++i) {
for(int j = 0; j < 10; ++j) {
int v = i%(limt/10)*10+j;
G[i].push_back(make_pair(v, false));
edge_cnt++;
}
}
//cout << edge_cnt << endl;
dfs(0, edge_cnt);
int pos = Maxn*10;
while(!S.empty()) {
int tmp = S.top().cur; S.pop();
str[--pos] = tmp%10+'0';
}
for(int i = 0; i < n-1; ++i)
str[--pos] = '0';
//cout << Maxn*10-pos << endl;
printf("%s", str+pos);
puts("");
}
return 0;
}
浙公网安备 33010602011771号