力扣——1015. 可被 K 整除的最小整数
1015. 可被 K 整除的最小整数
给定正整数 k ,你需要找出可以被 k 整除的、仅包含数字 **1** 的最 小 正整数 n 的长度。
返回 n 的长度。如果不存在这样的 n ,就返回-1。
注意: n 不符合 64 位带符号整数。
示例 1:
输入:k = 1
输出:1
解释:最小的答案是 n = 1,其长度为 1。
示例 2:
输入:k = 2
输出:-1
解释:不存在可被 2 整除的正整数 n 。
示例 3:
输入:k = 3
输出:3
解释:最小的答案是 n = 111,其长度为 3。
提示:
1 <= k <= 105
问题解析
首先我们很容易想到,如果是偶数,或者是以5为结尾的数,他们的倍数尾部绝对不会有1,自然不会满足条件。所以如果给的数k是偶数或者是5的倍数,我们直接返回-1即可。
然后如果我们枚举1的位数,来进行计算,复杂度高不说,而且即便是longlong结构,也只有19位数,而本题的结果动辄几百上千位数,所以这个做法显然是不行的。
这里要用到我们小学中就学到的竖式除法。
先用一个数做被除数num,逐步增加1的位数知道大于等于k为止。然后开始除,如果除完之后被除数num为0,则当前的位数就是答案。
如果num不为0,则我们给他后面加上一个1,然后继续用k除。
重复如上步骤,直到num为0为止。
在此过程中记录添加的1的位数,最后返回位数就是此题的答案。
AC代码
class Solution {
public:
int smallestRepunitDivByK(int k) {
if(k%2==0||k%5==0)return -1;
int num = 1, cnt = 1;
while (num < k)
{
num *= 10;
num += 1;
cnt++;
}
while (num)
{
cout << num / k;
num %= k;
if (num == 0)break;
cnt++;
num *= 10 ;
num++;
}
return cnt;
}
};