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

题目:任意给定一个正整数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     BigInt[i].clear();
 3 BigInt[1].push_back(0);
 4
 5 int NoUpdate = 0;
 6 //i 表示当前最高位是 10^i 次方   j表示 10^i % N的值 100 % N = ((10 % N) * 10) % N 注意 j避免表示大数的方法
 7 for(i=1,j=10%N; ; i++,j=(j*10)%N)
 8 {
 9     bool flag = false;
10     if(BigInt[j].size()==0)
11     {
12         flag=true;
13         //BigInt[j]=10^i,(10^i %N =j)
14         BigInt[j].clear();
15         BigInt[j].push_back(i);
16     }
17     for(k=1;k<N;k++)
18     {
19         if((BigInt[k].size()>0)&&(i>BigInt[k][BigInt[k].size()-1])&&(BigInt[(k+j)%N].size()==0))
20         {
21             //(i>BigInt[k][BigInt[k].size()-1])说明当前的余数不是因为在i循环时由早些的k循环处理中产生的
22             //BigInt[(k+j)%N]=10^i+BigInt[k]
23             flag=true;
24             BigInt[(k+j)%N] = BigInt[k];
25             BigInt[(k+j)%N].push_back(i);
26         }
27     }
28     if(flag==false) NoUpdate++;
29     else NoUpdate=0;
30     //如果经过一个循环节都没能对BigInt进行更新,就是无解,跳出。或者BigInt[0]!=NULL,已经找到解,也跳出
31     if(NoUpdate==N||BigInt[0].size()>0)
32         break;
33 }
34 if(BigInt[0].size()==0)
35 {
36     // M not exist;
37 }
38 else
39 {
40     //Find N*M=BigInt[0]
41 }

网上一个证明这M一定存在的思想:

解决这个问题首先考虑对于任意的N,是否这样的M一定存在。可以证明,M是一定存在的,而且不唯一。
简单证明:因为

这是一个无穷数列,但是数列中的每一项取值范围都在[0, N-1]之间。所以这个无穷数列中间必定存在循环节。即假设有s,t均是正整数,且s<t,有 。于是循环节长度为t-s。于是10^s = 10^t。因此有:
,所以

时间: 2024-10-11 22:30:16

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

第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 *

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

任意给定一个正整数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 } 但问题很快就出现了,什

编程之美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

编程之美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%

(转)找符合条件的整数

题目:任意给定一个正整数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整除.

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

好不容易把内容看懂~ 最主要的一句话:只需要将10k%N的结果与余数信息数组里非空的元素相加,再去模N,看看会不会出现新的余数~ 时间太紧迫~先把自己写的代码贴上,以后再详解 1 int FindMin(int N) 2 { 3 if(N <= 1) 4 return N; 5 6 int* A = new int[N];//这个是记录模N余i之后的数值 7 8 memset(A, -1, sizeof(int) * N); 9 int factor = 1; 10 A[1] = 1; 11 1

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

问题:给定整数N,求最小整数M,使得N*M的十进制表示中只含有1和0: 当M很大时,机器可能不能表示M,对问题转化:求以最小整数X,使得X的十进制表示中只含1和0,并且被N整除: 此问题必定有解:可参考:http://blog.csdn.net/spaceyqy/article/details/38337387 代码实现(具体思路参考编程之美或:http://www.cnblogs.com/jfcspring/p/3776388.html): 1 #include<iostream> 2 #i