编程之美2.8 | 找符合条件的整数

思路还是相当地巧妙。

求余数的话,(a+b)%n=(a%n+b%n)%n;

用vector来表示整数的话(出现1的位置),可以避免溢出。

注意第20行,在更新remainders[(j+r)%n]时,要确保每个remainders的每个序列都是递增的,不能存在相等的情况。

 1 #include <time.h>
 2 #include <math.h>
 3 #include <stdlib.h>
 4
 5 using namespace std;
 6
 7 long long findMInZeroOneNum(int n) {
 8         vector<vector<int> > remainders(n);
 9         remainders[1].push_back(0);
10
11         bool update = false;
12         int noupdate = 0;
13         for (int i = 1, j = 10 % n; ; j = (j * 10) % n, i++) {
14                 if (remainders[j].empty()) {
15                         remainders[j].push_back(i);
16                         update = true;
17                 }
18                 for (int r = 1; r < n; ++r) {
19                         if (remainders[r].empty()) continue;
20                         if (i <= remainders[r].back()) continue;
21                         if (!remainders[(j + r) % n].empty()) continue;
22                         remainders[(j + r) % n] = remainders[r];
23                         remainders[(j + r) % n].push_back(i);
24                         update = true;
25                 }
26                 if (!update) noupdate++;
27                 else noupdate = 0;
28                 if (noupdate == n || !remainders[0].empty()) break;
29         }
30
31         if (remainders[0].empty()) return -1;
32         else {
33                 long long ans = 0;
34                 for (int i = 0; i < remainders[0].size(); ++i) {
35                         ans += pow(10, remainders[0][i]);
36                 }
37                 return ans;
38         }
39 }
40
41 long long bruteForce(int n) {
42         if (n <= 0) return -1;
43         for (long long i = 1; ; ++i) {
44                 if (i % n != 0) continue;
45                 long long tmp = i;
46                 while (tmp) {
47                         int d = tmp % 10;
48                         if (d != 0 && d != 1) break;
49                         tmp /= 10;
50                 }
51                 if (tmp == 0) return i;
52         }
53         return -1;
54 }
55
56 int main() {
57         srand(time(NULL));
58         int n = rand() % 99;
59
60         cout << n << endl;
61         long long n1 = findMInZeroOneNum(n);
62         cout << n1 << endl;
63         long long n2 = bruteForce(n);
64         cout << n2 << endl;
65         if (n1 != n2) {
66                 cout << n << " " << n1 << " " << n2 << endl;
67         }
68
69         return 0;
70 }
时间: 2024-10-05 22:52:13

编程之美2.8 | 找符合条件的整数的相关文章

编程之美2.8——找符合条件的整数

任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0. 如N=3,M=39,N*M=111. [思路] 这么难的思路打死我也想不到[email protected][email protected]|||||.. 将题目转换为,求一个数X,使得X%N=0且X的十进制表示只含有1和0. 维护一个“余数数组”,对于从0到N-1的每一个余数,都有相应的最小X: 高位可以利用低位的余数归队,X=10^k+Y(10的k次方,^表示次方)X%N=(10^k%N+Y%

第2章 数字之魅——找符合条件的整数

找符合条件的整数 问题描述 任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0. 解决这个问题首先考虑对于任意的N,是否这样的M一定存在.可以证明,M是一定存在的,而且不唯一.简单证明:因为 这是一个无穷数列,但是数列中的每一项取值范围都在[0, N-1]之间.所以这个无穷数列中间必定存在循环节.即假设有s,t均是正整数,且s<t,有 .于是循环节长度为t-s.于是10^s = 10^t.因此有:,所以 例如,取N=3,因为10的任何非负次方模3都为

【编程之美】2.8 找符合条件的整数

给定一个正整数N,求一个最小的正整数M(M > 1),使得N * M的十进制表示中只有0和1. 我的思路: 从最低位到最高位找M,每次使得乘积的最后面多一位符合0.1的条件. 那么先找能够让末尾数字变成0的备选项 举例若N的个位数是9  考虑从后面来的进位 c 让 x * 9 + c 的末尾是0或1 设个位数字为9 则eligibleNum中存储的数字eligibleNum[0][0] = 0 因为9 * 0 + 0 = 0 末尾符合0或1 eligibleNum[0][0] = 9 因为9 *

编程之美-2.8 找到符合条件的整数

一.问题描述 任意给定一个正整数N,求一个最小正整数M(M>1),使得N*M的十进制形式只含1和0. 比如 N=99,M=1 122 334 455 667 789 ,N*M=111 111 111 111 111 111; M就是当N=99时,符合条件的数 二.解题思路 考虑将问题转化为:找只含有0和1的能被N整除的最小正整数.可以看出这是和原问题等价的. 那么需要将0和1组成的所有数从小到大遍历吗? 这样的话,如果寻找的数是k位,则需要搜索2k-1个数才能得到结果. 这里采用的方式是在计算中

【编程之美】找符合条件的整数

任意给定一个正整数N,求一个最小的正整数M(M > 1),使得N*M的十进制表示形式里只含有1和0. 看了题目要求之后,我们首先想到从小到大枚举M的取值,然后再计算N*M,最后判断它们的乘积是否只含有1和0.大体思路可以用下面的伪代码实现: 1 for (M = 2; ; M++) 2 { 3 product = N * M; 4 if (hasOnlyOneAndZero(product)) 5 output N, M, product, and return; 6 } 但问题很快就出现了,什

编程之美---找符合条件的整数

题目:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0. 解法:原问题转化为求一个最小的正整数X,使得X的十进制表示形式里只含有1和0,并且X被N整除.于是乎就成了遍历二进制整数一样遍历X的各个取值,但是如果X的最终结果又K位,则要循环搜索2K 次.因此,可以建立一个长度为N的“余数信息数组”,这个数组的第i位保留已经出现的最小的模N为i的X.用BigInt[i]可能很大,只须记下1的位置即可. 1 for(i=0;i<N;i++) 2 BigIn

(转)找符合条件的整数

题目:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0.解决这个问题首先考虑对于任意的N,是否这样的M一定存在.可以证明,M是一定存在的,而且不唯一.简单证明:因为 这是一个无穷数列,但是数列中的每一项取值范围都在[0, N-1]之间.所以这个无穷数列中间必定存在循环节.即假设有s,t均是正整数,且s<t,有 .于是循环节长度为t-s.于是10^s = 10^t.因此有:,所以 例如,取N=3,因为10的任何非负次方模3都为1,所以循环节周期为1.

找符合条件的整数

题目: 任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式只含有1和0 . 分析: 将问题"求一个最小的正整数M,使得N*M的十进制表示形式里只含有1和0"转换为求一个最小的正整数X,使得X的十进制表示形式里只含有1和0,并且X被N整除.

【目录】编程之美

编程之美 2.1 二进制数中1的个数 2.2 阶乘 2.4 1的数目 2.5 寻找最大的k个数 2.6 精确表达浮点数 2.7求最大公约数 2.8 找符合条件的整数 2.10 求数组中最大的数和最小的数 2.12快速寻找满足条件的两个数 2.13 子数组的最大乘积 2.14 求数组的子数组之和的最大值 2.15 子数组之和的最大值(二维) 2.16 求数组的最大递增子序列 2.17 数组循环位移 2.18 数组分割 2.19 区间重合判断 2.20程序理解和时间分析 2.21 只考加法的面试题