博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU-4474 Yet Another Multiple Problem BFS搜索
阅读量:7117 次
发布时间:2019-06-28

本文共 2406 字,大约阅读时间需要 8 分钟。

题意:给定一个数N(1<=N<=10000),求N的一个最小的倍数能够被N整除。

解法:粗看起来题意简单,但是确无从下手,其实正确的解法就是通过搜索来搞定,由于N不太,因此N的余数类也不会很大,采用从小到大的枚举策略能够使得后面达到的同余类状态不及前面的优秀,这样就能够在非常短的时间内找到答案。

bfs过程中对于在状态与状态之间建立前驱指针,这样就能够输出最后的结果。

一个状态需要记录以下值:1.当前状态对N的余数;2.当前放置的数字;3.前驱指针。

状态之间的转移:mod' = (mod*10 + digit) % N

从1位开始依次枚举,然后扩大到2位,3位.....

代码如下:

#include 
#include
#include
#include
#include
using namespace std;int N, M;char hav[15];char vis[10005];struct Node { int mod, f; // mod表示对N取余后的值,f表示父亲节点的编号 char digit; // 当前放置的数字为多少 }info, que[10005];void show(int x) { if (que[x].f != -1) { show(que[x].f); } printf("%d", que[x].digit);}inline bool ok(int x, int &ans) { if (que[x].mod == 0) { ans = x; return true; } return false;}void bfs() { int ans, front = 0, tail = 0; bool finish = false; for (int i = 1; i < 10; ++i) { // staring from 1 if (!hav[i]) { // 如果这个数码没有被限制 que[tail].mod = i % N; if (vis[que[tail].mod]) continue; // 判定这个余数是否已经走过 vis[que[tail].mod] = 1; que[tail].digit = i; que[tail].f = -1; // -1是一个特殊的标识,表示到了根节点 // 把一个合法的初始化根节点加入到队列中去 if (ok(tail, ans)) { finish = true; break; } ++tail; } } while (!finish && front != tail) { info = que[front++]; // 取出队首元素 for (int i = 0; i < 10; ++i) { if (!hav[i]) { que[tail].mod = (info.mod * 10 + i) % N; if (vis[que[tail].mod]) continue; vis[que[tail].mod] = 1; que[tail].digit = i; que[tail].f = front-1; // 保留上一个状态的编号 if (ok(tail, ans)) { finish = true; break; } ++tail; } } } if (finish) { show(ans); puts(""); } else { puts("-1"); }}int main() { int c, ca = 0; while (scanf("%d %d", &N, &M) != EOF) { memset(hav, 0, sizeof (hav)); memset(vis, 0, sizeof (vis)); for (int i = 0; i < M; ++i) { scanf("%d", &c); hav[c] = 1; // 标志为1的数字不能够使用 } printf("Case %d: ", ++ca); bfs(); } return 0; }

 

转载于:https://www.cnblogs.com/Lyush/archive/2013/04/25/3042376.html

你可能感兴趣的文章
Linux 下 Oracle 10g 安装“三部曲”
查看>>
ubuntu面板恢复方法
查看>>
高通总裁回应博通收购:5G就要来了 合作伙伴需要定心丸
查看>>
CCNP-18 IS-IS试验1(BSCI)
查看>>
Comet和WebSocket
查看>>
C#程序实现窗体的最大化/最小化
查看>>
使用委托进行异步编程
查看>>
Gmail在outlook设置
查看>>
scala模式匹配
查看>>
JPush删除别名及回调函数(SWIFT)
查看>>
silverlight 跨域socket
查看>>
编程不是功能实现了就可以了
查看>>
利用Dockerfile构建一个nginx容器
查看>>
Linux/Freebsd下时间转化
查看>>
VMware vSphere 5.1 群集深入解析(十五)-DRS推荐向导
查看>>
sklearn.metrics.auc
查看>>
Context Switch Definition(译文)
查看>>
Linux中通过/proc/stat等文件计算Cpu使用率(一)
查看>>
微软MED-V虚拟化实战教程之一部署
查看>>
linux 下用python 遍历文件夹
查看>>