【回炉重造】POJ-1426.Find The Multiple 题解
题目链接:POJ-1426.Find The Multiple
题目
题意
给你一个正整数 n ,让你找一个正整数 m
- m 必须能被 n 整除
- m 是只由 0 和 1 这两种数字组成的 十进制 数
请输出 n 对应的 m 如果有多个结果输出任意一个即可
解题思路
由于所求十进制数可能会有100位,显然直接整除是不可能的。
但是如果我们:
- 先用最高位除以 n 得到余数 y
- y*10+次高位 再除以 n 得到新的余数 y
- 以此类推
- 当最后能整除的时候,就得到了一串数字
例如:
n | m | 过程 |
---|---|---|
2 | 10 | 1%2 = 1 10%2 = 0 得到结果 10 |
6 | 100100100100100100 | 1%6=1 10%6=4 40%6=4 41%6=5 50%6=2 20%6=2 21%6=3 30%6=0 得到结果 10010010 |
表格中第二个例子最后得到了10010010
此时已经可以被6整除,后面多个0无非是结果多个0,100100100
重复一遍无非是结果重复一遍,有兴趣可以自己推算一下
因此我们就可以确定这道题只需要假设每一位的 0和1 并计算是否能整除,就可以得到结果
这里用 深搜 ,每次递归假设一位的两种情况:【广搜要记录的东西太多可能超内存
- 题上说了不会超过100位,所以我们就定一个超过 100 位的 bitset 位容器
- 为了符合逻辑我从99到0来进行计数
- dfs 的两个参数是 余数 y 和 深度 d
- 余数 y 就是每次要除以 n 的数,如果能整除就返回结果了
- 深度 d 是来限制递归的层数,如果小于 0 说明已经超过100位了,直接舍弃,返回上层寻求别的结果
- 把结果放到宏定义,最后遍历的位的范围需要注意一点
- 以上思路结合代码思考更佳
代码
//
// _ _ ___ ____ ___ ____ _____
//| | | | / _ \ _ __ / ___/ _ \| _ \| ____|
//| |_| | | | | | '_ \ | | | | | | | | | _|
//| _ | | |_| | | | | | |__| |_| | |_| | |___
//|_| |_|___\___/|_| |_| \____\___/|____/|_____|
// |_____|
//
#include <iostream>
using namespace std;
typedef int hip;
#include <bitset>
const int maxn = 1<<7;
bitset<maxn> b;
hip r, n;
bool dfs(hip y, hip d) {
if (d<0) return false;
if (y%n == 0) {r = d; return true;}
hip ny = int((y%n)*10);
b.reset(d);
if (dfs(ny, d-1)) return true;
b.set(d);
if (dfs(ny+1, d-1)) return true;
return false;
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
while (true) {
cin >> n;
if (!n) break;
b.reset();
b.set(99);
r = 100;
if (dfs(1, 98)) {
for (hip i=99; i>r; i--) cout << b[i];
cout << endl;
}
}
return 0;
}