卧薪尝胆,厚积薄发。
Code
Date: Wed Oct 10 20:05:15 CST 2018 In Category: NoCategory

Description:

求一个字典序最小的字符串包括从 $0$ 到 $10^n-1$ 所有字符串。
$1\leqslant n\leqslant6$

Solution:

把字符串看作边,在删掉第一个字符和删掉最后一个字符的两个字符串之间连边,然后跑一个欧拉回路,要写手工栈。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define MAXN 1000010
int power[8] = {1,10,100,1000,10000};
struct edge
{
int to,nxt;
bool tag;
edge(){tag = false;}
}e[MAXN];
int edgenum = 0;
int lin[MAXN];
void add(int a,int b)
{
e[edgenum].to = b;e[edgenum].nxt = lin[a];lin[a] = edgenum;++edgenum;
return;
}
int s[MAXN],top = 0;
int stack[MAXN],stop = 0;
void dfs()
{
stack[++stop] = 0;
int k;
while(stop != 0)
{
k = stack[stop];
bool tag = false;
for(int &i = lin[k];i != -1;i = e[i].nxt)
{
if(!e[i].tag)
{
e[i].tag = true;
tag = true;
stack[++stop] = e[i].to;
break;
}
}
if(tag)continue;
--stop;
s[++top] = k % 10;
}
return;
}
int main()
{
int n;
while(scanf("%d",&n) && n != 0)
{
if(n == 1)
{
puts("0123456789");
continue;
}
memset(lin,-1,sizeof(lin));
memset(e,0,sizeof(e));
edgenum = 0;
top = 0;
for(int i = power[n - 2] - 1;i >= 0;--i)
{
for(int k1 = 9;k1 >= 0;--k1)
{
for(int k2 = 9;k2 >= 0;--k2)
{
add(k1 * power[n - 2] + i,i * 10 + k2);
}
}
}
dfs();
for(int i = 1;i <= n - 2;++i)putchar('0');
while(top != 0)putchar(s[top--] + '0');
puts("");
}
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡