题目链接:点我啊╭(╯^╰)╮
题目大意:
给出一个整数 n n n, ( 1 < = n < = 200 ) (1 <= n <= 200) (1<=n<=200)。求出任意一个它的倍数 m m m,要求 m m m必须只由十进制的 ′ 0 ′ '0' ′0′或 ′ 1 ′ '1' ′1′组成
解题思路:
思考一下,发现只能是
0
0
0和
1
1
1枚举,如果不放到搜索里,可能想不到BFS。
那么其实我们思考后,只需要枚举每一位模
n
n
n判断是否有余数,第一位为
1
1
1,若第
i
i
i为
x
x
x,第
i
+
1
i+1
i+1为就是
(
x
×
10
+
0
)
(x×10+0)
(x×10+0)%
n
n
n与
(
x
×
10
+
1
)
(x×10+1)
(x×10+1)%
n
n
n两种情况,用到同余模定理:
(
a
∗
b
)
(a*b)
(a∗b) %
n
=
n =
n=
(
a
(a
(a%
n
×
b
n \times b
n×b%
n
)
n)
n)% n
(
a
+
b
)
(a+b)
(a+b)%
n
=
n =
n=
(
a
(a
(a%
n
+
b
n +b
n+b%
n
)
n)
n)% n
代码思路:
这里不给BFS代码,本人也是看了别人的题解之后感触良多,这里用一个循环来模拟BFS双入口,实现过程值得仔细揣摩和思考
核心:取模、联想搜索、也能打表~
这里贴出比较好的题解:对,就是我!!!
#include <iostream>
#include <cstdio>
using namespace std;
int mod[524286]; //保存每次mod n的余数
//由于198的余数序列是最长的
//经过反复二分验证,436905是能存储198余数序列的最少空间
//但POJ肯定又越界测试了...524286是AC的最低下限,不然铁定RE
int main() {
int n, i;
while(scanf("%d", &n), n) {
mod[1] = 1 % n; //初始化,n倍数的最高位必是1
for(i=2; mod[i-1]!=0; i++)
mod[i] = (mod[i/2]*10 + i%2) % n;
// 利用同余模定理,从前一步的余数mod[i/2]得到下一步的余数mod[i]
// mod[i/2]*10+i%2模拟了BFS的双入口搜索
// 当i为偶数时,+0,即取当前位数字为 0。为奇数时,则 +1,即取当前位数字为 1
i--;
int pm=0;
while(i) {
mod[ pm++ ] = i % 2; //把*10操作转化为%2操作,逆向求倍数的每一位数字
i /= 2;
}
while(pm) printf("%d", mod[--pm]); //倒序输出
printf("\n");
}
}