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

时间:2022-01-28 00:38:02
题目:任意给定一个正整数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&lpar;N&rpar;&comma;且要求不能用非基于比较的排序

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

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

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

  6. Bellman&lowbar;Ford算法&lpar;求一个点到任意一点的最短距离)

    单源最短路问题是固定一个起点,求它到任意一点最短路的问题. 记从起点出发到顶点 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&sol;已知一个等式,求另一个最小值

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

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

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

随机推荐

  1. 盒子模型简单理解(box-sizing)

    普通解析: 概念图示和公式: html结构 <div class="num1"></div> 1.只写 width.height(写背景是为了区分) .nu ...

  2. 贪吃蛇的java代码分析(一)

    自我审视 最近自己学习java已经有了一个多月的时间,从一开始对变量常量的概念一无所知,到现在能勉强写几个小程序玩玩,已经有了长足的进步.今天没有去学习,学校里要进行毕业答辩和拍毕业照了,于是请了几天 ...

  3. 在rails 4 中 使用 CSV 组件来 把csv文件导入到数据库

    class HardWorker include Sidekiq::Worker require 'CSV' def perform(file_path) csv_text = File.read(f ...

  4. java&colon;JDBC详解

    JDBC全称为:Java DataBase Connectivity(java数据库连接). SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC.     简单 ...

  5. jboss jms 实例

      最近温习了下EJB和JMS,整理了下思路,和大家分享下P2P和Pub/Sub的demo :JBoss 7 集成了HornetQ,JMS可以在HornetQ中间件运行,有时间在和大家分享关于Horn ...

  6. BZOJ-1008 越狱 数论快速幂

    1008: [HNOI2008]越狱 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 6192 Solved: 2636 [Submit][Status] ...

  7. C&num; 将DataTable装换位List&lt&semi;T&gt&semi; 泛型

    public List<T> GetList<T>(DataTable dt) where T:new() { List<T> DateLists = new Li ...

  8. BZOJ&lowbar;4551&lowbar;&lbrack;Tjoi2016&amp&semi;Heoi2016&rsqb;树&lowbar;树剖&plus;线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  9. GitHub 1W star 成就达成!

    起因 感谢各位大佬的支持收获了人生第一个(很有可能也是唯一一个)1W star 项目. 从今年一月份创建项目至今 8 个月时间. 一共关闭了 27 个 issue,47 个 RP,总共有 11 位小伙 ...

  10. BZOJ3022 &colon; &lbrack;Balkan2012&rsqb;The Best Teams

    将选手和询问按照年龄排序,即可去掉年龄的限制. 将所有选手按水平排序后维护线段树,显然最优解一定是从大到小贪心选择. 线段树上每个节点维护: $g[0/1]:r+1$不选/选的时候,$l$选不选. $ ...