无心人 发表于 2008-4-27 20:29:29

来点有意思的问题,2的方幂的开始数字问题

显然,对$2^n$来说,不同的n其开始数字是不同的,有的以1开始有的以2开始,等等。
当然也可以考虑开始两位数字。

容易证明,$2^n$可以任何数字开始。

现在的问题是,请求出$10000$以内的数字$m$对应的$2^n$使$2^n$以$m$开始且$n$最小。

:)
很有意思是不是?

medie2005 发表于 2008-4-27 20:44:54

若m是k位数,则只需要求满足10^log10(2^n)=10^(n*log10(2))的前k位的值是m 的n就ok了。

无心人 发表于 2008-4-27 20:51:13

那我觉得不如用10进制加法,逐渐加,然后取前4位效率高

mathe 发表于 2008-4-29 09:13:45

主要m才4位,要求不高

无心人 发表于 2008-4-29 11:22:34

:)

你觉得怎么做合适?

medie2005 发表于 2008-4-29 11:25:57

说一下我的解法,思路还是2#的.
我们记d的小数部分为{d}.
对任意给定的k位数m,我们令c1=log10(m/10^(k-1)), c2=log10((m+1)/10^(k-1)).
那么,我们现在只要找满足 c1<={n*log10(2)}<c2的最小n就可以了.
解这个不等式非常简单,只需要注意到{n*log10(2)}是分段递增的.
另外,需要注意的是,当m=10^t时,上面方法求出来的n是0,因此,我们只需要再对这种情况特殊处理就ok了.这个也比较简单了
举个例子,m=2;
c1=log10(2), c2=log10(3).
因此,我们找到了n=1.

medie2005 发表于 2008-4-29 11:30:28

发一下代码(未对m=10^t的做特殊处理):

#include <iostream>
#include <cmath>
using namespace std;
const double log10_2=log10(2);
int main()
{
for( int m=1; m<10000; ++m ){
cout<<"m=="<<m<<"";
intL1=int(log10(m));
double c1=log10(m/pow(10,L1)), c2=log10((m+1)/pow(10,L1));
bool flag=true;
for( int k=0; flag; ++k ){
   double s=k*log10_2;
   int    int_s=int(s);   
   if( s-int_s>=c1 && s-int_s<c2 ){
    flag=false;
    cout<<k<<endl;
   }
}
}
return 0;
}

medie2005 发表于 2008-4-29 11:33:32

上面解c1<={n*log10(2)}<c2的方法十分朴素,但效率还是不错的.当然有其他更好的办法,模拟手工解这个不等式就是一个十分好的算法.

无心人 发表于 2008-4-29 11:45:04

:)

看下运行的时间和一些结果好不好么?

medie2005 发表于 2008-4-29 12:04:06

帖一下结果(m=10^t的结果除1之外的都不正确).
用时:1874 ms.
页: [1] 2 3
查看完整版本: 来点有意思的问题,2的方幂的开始数字问题