题目:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。
解法一:暴力求解。从1开始查找M,然后判断M*N=X这个数字是否只含有0,1.

解法二:由于没有直接的数学方法能帮我们直接得到M的值,所以我们只能进行搜索。由于相对M,乘积N*M具有明显的特征,需要搜索的空间要小很多,所以我们对乘积N*M进行搜索。如果N*M的结果有K位,则要循环2^K次,我们发现K的结果能轻易超过40,所以这个运行时间还是相当长。同余运算具有等价关系,mod N = i(0<=i<N)构成了N个等价类,将正整数集进行划分。对于每个等价类,我们只需要判断其中最小的元素加上10^K是否能被N整除,这样搜索空间就从2^K次减少到(K-1)*N步,而N的值一般要远远小于M的值,但要O(N)的空间复杂度。

由于无论M还是N*M的位数都相当大,所以我们用大整数表示M和N*M。由于要N个大整数,所以N不能为大整数,即其值最好取一百万以内。

代码实现入下:

#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
bool FindNumber(int N,vector<int> *BigInt);
int main()
{
int N,i;
cout<<"Input a positive integer: ";
cin>>N;
vector<int> *BigInt=new vector<int>[N];//用来存放余数为0 ~ N最小数字,数字表示,如整数1001,则存为1001=10^0+10^3=(0,3),适合大数的表示
for(i=0;i<N;i++)
BigInt[i].clear();
bool found=FindNumber(N,BigInt);
if(found)
{
int len=BigInt[0][BigInt[0].size()-1]+1;
char *product=new char[len+1];
int product2=0;
for(i=0;i<len;i++)
product[i]='0';
product[len]='\0';
vector<int>::iterator iter;
for(iter=BigInt[0].begin();iter!=BigInt[0].end();iter++)
{
product2=product2+pow(10,*iter);
product[*iter]='1';
}
int j=len-1;
i=0;
while(i<j)
{
char tmp=product[j];
product[j]=product[i];
product[i]=tmp;
i++;
j--;
}
int M=product2/N;
//product和product2都对应着乘积结果,但是product2对应着整型,乘积过大时,product2可能不会得到正确的结果;
//product对应着乘积的字符串,可以表示大数的乘积结果,M为product2/N,即为要求的数,当product2溢出时,不是正确的结果,
//那种情况下,需要用product/N,其中product为乘积的字符串表示,这里没有求解,读者可以自行解决。
cout<<N<<" * "<<M<<" = "<<product<<" , "<<product2<<endl;
delete []product;
}
else
cout<<"Can not find M!"<<endl;
delete []BigInt;
return 0;
}
bool FindNumber(int N,vector<int> *BigInt)
{
int i,j,k;
BigInt[1].push_back(0);
int NoUpdate=0;
for(i=1,j=10%N; ; i++,j=(j*10)%N)
{
bool flag=false;
if(BigInt[j].size()==0)
{
flag=true;
// BigInt[j]=10^i,(10^i)%N=j
BigInt[j].clear();
BigInt[j].push_back(i);
}
for(k=1;k<N;k++)
{
//有新的余数出现
if((BigInt[k].size()>0)&&(i>BigInt[k][BigInt[k].size()-1])
&&(BigInt[(k+j)%N].size()==0))
{
//BigInt[(k+j)%N]=10^i+BigInt[k]
flag=true;
BigInt[(k+j)%N]=BigInt[k];
BigInt[(k+j)%N].push_back(i);
}
}
if(flag==false)
NoUpdate++;
else
NoUpdate=0;
//如果经过一个循环节都没能对BigInt进行更新,就是无解,跳出,
//若有N次没更新过余数信息,则存在c>=0,10^(c+1)modN,...,10^(c+N)modN中必有两个是相等的,
//那么继续进行下去也不会再更新了
//或者BigInt[0]!=NULL,已经找到解,也跳出.
if(NoUpdate==N||BigInt[0].size()>0)//若有N次没更新过余数信息,则存在c>=0,10^(c+1)modN,...,10^(c+N)modN中必有两个是相等的,那么继续进行下去也不会再更新了
break;
}
if(BigInt[0].size()==0)
return false;
else
return true;
}

我们可以证明对于任意的N,一定存在M,使得N*M的乘积的十进制表示只有0和1。证明过程见:http://blog.csdn.net/jcwkyl/article/details/3859155

任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。的更多相关文章

  1. 38 写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度。

    题目:写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度. public class _038PrintLength { public static void main(Stri ...

  2. 写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度

    import java.util.Scanner; /** * [程序38] * * 题目:写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度. * * @author Jame ...

  3. 谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前k个数怎么做?

    谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前k个数怎么做? 分析: "假设两个整数数组为A和B,各有N个元素,任意两个数的和组成的数组C有N^2个元素. ...

  4. 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序

    题目: 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序 public static int maxGap(int nums[]) { if ( ...

  5. 【C语言】求旋转数组的最小数字,输入一个递增排序的数组的一个旋转,输出其最小元素

    //求旋转数组的最小数字,输入一个递增排序的数组的一个旋转,输出其最小元素 #include <stdio.h> #include <string.h> int find_mi ...

  6. Bellman_Ford算法(求一个点到任意一点的最短距离)

    单源最短路问题是固定一个起点,求它到任意一点最短路的问题. 记从起点出发到顶点 i 的最短距离为d[i],则有以下等式成立 d[i]=min{d[j]+(从j到 i 的边的权值) 看代码 #inclu ...

  7. 求一个集合的所有真子集 Python

    给定一个集合,元素均为正整数且不重复,求该集合的所有子集 # -*- coding: utf-8 -*- """ Created on Tue Oct 10 09:04: ...

  8. poj1190,DFS/已知一个等式,求另一个最小值

    7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体.  设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱. ...

  9. 求一个数组中第K小的数

    面试南大夏令营的同学说被问到了这个问题,我的第一反应是建小顶堆,但是据他说用的是快排的方法说是O(n)的时间复杂度, 但是后来经过我的考证,这个算法在最坏的情况下是O(n^2)的,但是使用堆在一般情况 ...

随机推荐

  1. QWidget 键盘事件 焦点(源代码级别研究)

    在Qt中,键盘事件和QWidget的focus密不可分:一般来说,一个拥有焦点(focus)的QWidget或者grabKeyboard()的QWidget才可以接受键盘事件. 键盘事件派发给谁? 如 ...

  2. android HttpGet 另开线程获取网络数据问题

    android跨线程通讯可以使用android.os.Handler-android.os.Message这两类对象完成. public static void getResultForHttpGet ...

  3. linux 用户空间获得纳秒级时间ns

    一.引言 我们在测试程序的性能的时候往往需要获得ns级的精确时间去衡量一个程序的性能,下面介绍下linux中用户空间获得ns级时间的方法 二.用户空间获得ns级时间 使用clock_gettime函数 ...

  4. hdu 1757 A Simple Math Problem(矩阵快速幂乘法)

    Problem Description Lele now is thinking about a simple function f(x). If x < f(x) = x. If x > ...

  5. 学用 ASP.Net 之 System.Math 类

    本文来自:http://www.cnblogs.com/del/archive/2011/01/03/1924746.html   成员: /* 字段 */ Math.E;      //2.7182 ...

  6. Android自己定义组件系列【7】——进阶实践(4)

    上一篇<Android自己定义组件系列[6]--进阶实践(3)>中补充了关于Android中事件分发的过程知识.这一篇我们接着来分析任老师的<可下拉的PinnedHeaderExpa ...

  7. UVA 507 - Jill Rides Again 动态规划

      Jill Rides Again  Jill likes to ride her bicycle, but since the pretty city of Greenhills where sh ...

  8. 【最小费用最大流】【HDU1533】【Going Home】

    题意 给你一个类似这样的图 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 问所有H移动到所有m上花费最少的步数 以所有H ...

  9. jQuery关于mouseover和mouseenter的区别

    原生的mouseenter是dom3级的事件,对于jQuery等一些框架已经实现了这个事件.但是它到底跟mouseover有什么区别? jQuery在实现这两个事件的时候,mouseover支持事件冒 ...

  10. meta 标签整理

    <!-- 声明文档 --> <meta charset='utf-8'> <!-- 指示IE以目前可用的最高模式显示内容 --> <meta http-equ ...