题目链接

非递归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;
 }