hdu 4474 Yet Another Multiple Problem 模型转换 BFS搜索 根据剩余类建图广搜
题意:
给一个N(n<=1e4), M个数字(长度为1),问最小的数x(x%n=0) 不包含这m个数。
思路:
直接求,没想出解法.
对于一个数 x%n = m, 则 x` = x*10+i , 有 m` = (m*10+i)%n
我们可以利用 除了M个数字外的 数来构造这个 X.
因为需要最小的, 则其长度与字典序排列皆最小. 通过BFS进行搜索. 每一个 模n的余数之取第一次出现的,
因为之后再出现的. 只可能更长或者更大. 必定不是最优解.
搜索节点,保存三个信息: 当前x的最后一位, 当前x%n的余数, 当前节点的父亲节点.
结果输出利用记忆父亲节点 ,然后递归输出即可.
View Code
#include<cstdio> #include<cstring> #include<cstdlib> const int N = (int)1e4+10; struct node{ int m, f; char c; }Q[N], tmp; bool vis[N],legal[10]; int n, m; void print(int k){ //if( k == -1 ) return; if( Q[k].f != -1 ) print(Q[k].f); printf("%c", Q[k].c ); } int main(){ int Case = 1; while( scanf("%d%d",&n,&m) != EOF){ memset( vis, 0, sizeof(vis)); memset( legal, 0, sizeof(legal)); for(int x, i = 0; i < m; i++){ scanf("%d",&x); legal[x] = 1; } int l = 0, r = 0, res = -1; for(int i = 1; i < 10; i++){ if( !legal[i] ){ tmp.c = i+'0'; tmp.m = i%n; tmp.f = -1; // if( !vis[tmp.m] ){ vis[tmp.m] = 1; Q[r++] = tmp; if( tmp.m == 0 ){ res = r-1; break; } // } } } while( (l < r) && (res==-1) ){ for(int i = 0; i < 10; i++){ tmp.m = (Q[l].m*10+i)%n; tmp.c = i+'0'; tmp.f = l; if( !legal[i] && !vis[tmp.m] ){ vis[tmp.m] = 1; Q[r++] = tmp; if( tmp.m == 0 ){ res = r-1; break; } } } l++; } printf("Case %d: ", Case++); if( res == -1 ) printf("-1\n"); else {print(res);puts("");} } return 0; }