您的位置:首页 > 其它

POJ-1780 Code 欧拉路径

2013-03-27 22:29 288 查看
题意:破解一套1-6位长度密码的系统,寻找这样一个序列:对于N位的密码10^N+N-1长度的连续的长为N的串能够枚举完所有的密码。

解法:构图之后直接dfs会超内存,因此需要使用栈来实现。调了很久。

代码如下:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

int N, mod, head[100005];
int idx, lim, edge, top;
int stk[1000100];

struct Edge {
int v, next;
}e[1000100]; // 每个节点只能够引出10条边

char vis[1000100];

void insert(int a, int b) {
e[idx].v = b;
e[idx].next = head[a];
head[a] = idx++;
}

void dfs() {
stk[top++] = 0;
while (1) {
int flag = 0;
int v = stk[top-1]; // 取出栈顶元素
if (top == edge-(N-2)) { // 由于遍历的是点,因此从一个点N个9到N个0最终无法到达,中间也就少了N-2个状态
return;
}
for (int i = head[v]; i != -1; i = e[i].next) {
if (!vis[i]) {
flag = 1;
vis[i] = 1;
stk[top++] = e[i].v;
break;
}
}
if (!flag) {
--top;
}
}
}

int main() {
while (scanf("%d", &N), N) {
if (N == 1) {
printf("0123456789\n");
continue;
}
idx = top = 0;
memset(head, 0xff, sizeof (head));
memset(vis, 0, sizeof (vis));
lim = 1;
for (int i = 1; i < N; ++i) {
lim *= 10;
}
edge = lim * 10;
mod = lim / 10; // mod用来提取后后几位
for (int i = 0; i < lim; ++i) {
for (int j = 9; j >= 0; --j) { // 十个状态转移
insert(i, (i%mod)*10+j);
}
}
dfs();
for (int i = 0; i < top-1; ++i) {
printf("%d", stk[i]/mod);
}
printf("%d", stk[top-1]);
for (int i = 1; i < N; ++i) {
printf("0");
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: