对于一个给定的 [0,10000] 内的不能被 2 或 5 整除的整数 n,n 放大某些倍数后,结果会是仅由很多 1 组成的一个数 a。现在请你找出最小的那个 a 中包含的 1 的个数。
输入格式
输入包含多组测试数据。每组输入为一个整数 n(0 ≤ n ≤ 10000)。
输出格式
对于每组输入,输出最小的那个 aa 中包含的 11 的个数。
输出时每行末尾的多余空格,不影响答案正确性
样例输入
3
7
9901
样例输出
3
6
12
解题思路:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int main(){
int n,k,c;
while(scanf("%d",&n)!=EOF){
k = c = 1;
while(k < n){
k = k * 10 + 1;
c++;
}
while(k % n){
k = k % n * 10 + 1;
c++;
}
printf("%d\n",c);
}
return 0;
}
这题思路:就是从小到大枚举全由1组成的数,直到找到第一个能被n整除的就是a,输出它的1的个数。
k基本可以认为就是那个全由1组成的数,c就是它包含的1的个数,枚举下一个k的方法就是k = k * 10 + 1;,这能理解吧?因为:
11=1 * 10 + 1
111=11 * 10 + 1
1111=111 * 10 + 1
a要能被n整除,至少a要大于等于n吧?所以第一个循环while(k < n),就是找到第一个大于等于n并且全由1组成的数。
然后如果k不能整除n,也就是while(k%n),就继续枚举咯。但是第二个循环中枚举下一个全由1组成的数用的是k = k % n * 10 + 1;而不是k = k * 10 + 1;,这是因为int存储的整数范围有限,一直k = k * 10 + 1的话很快就会超过int的存储范围,由于k是否能整除n是使用取模操作来判断的,即k % n。
而取模操作有如下数学性质、模运算的重要结论:
(ab)%p = (a%pb)%p
(a+b)%p = (a%p+b)%p
具体证明过程这里不说了,想知道的话自己查资料。
那么(k%n10+1)%n==(k10+1)%n,由于题目中n < 1w,k % n < 1w,k%n*10+1<10w,所以用k = k % n * 10 + 1能保证k永远在int的范围内,同时k % n==所枚举的那个全由1组成的数%n。
上面的解释摘自百度知道 ,不作任何观点阐述