UVA 701 The Archeologists' Dilemma

UVA_701

    看了别人的解题报告之后,发现可以枚举剩余数字的位数,我们不妨设其为k,那么我们会得到不等式,N*10^k<=2^E<N*10^k,化简之后就可以得到log2(N)+k*log2(10)<=E<log2(N+1)+k*log2(10),我们设左右边界为a、b的话,问题就等价于如果在枚举k的过程中出现了[a,b)内有一个整数点的话,那个值就是E。

    首先来讲,由于b-a=log2((N+1)/N)<log2(2)=1,所以区间内如果出现整数点的话最多只有一个。接着,我们要解决的问题就是,随着我们不断地枚举k,是否一定在某一刻内出现[a,b)内有一个整数点的情况呢?

    对于这个问题我是这样想的,实际我们就是希望b-a这么宽的区间能够覆盖某个整数点,而对于k*log2(10)来讲,由于log2(10)是一个无理数,因此k*log2(10)-[k*log2(10)]不会有一个固定的整数周期,甚至不会出现两个不同的k使得它们的的值相等,这点可以用反证法证明。再加之k是整数,感觉上这个表达式的值应该在[0,1)之内分布的比较均匀,这样我们多次枚举之后,应该会出现某一时刻使得b-a这么宽的区间覆盖一个整数点。

    当然,前面只是感觉,也只是说理论上可以找到,但我们不妨分析一下b-a的取值,在最坏的情况下,区间长度只有7*10^(-10)左右,即便前面所说的表达式的值分布得再均匀,1s也不过能细化到10^(-8),也就是说大概能保证区间[a,b)长度是10^(-8)左右的数据能在1s之内找到解,这远远不能满足最坏的情况。不信的话可以把这种枚举的程序出一些9位数的数据试一下,就会发现程序跑得很慢,因为通常找到的解是8位数以上的。

    总而言之,我现在还没找到很“有效”的算法,之所以枚举能过,应该也是数据出得比较小的缘故。

 

    后来听YTQ说,由于这个题目是2000年出的,所以可能题目中所指的整数E是在65536之内的,这样的话枚举范围就很小了。

#include<stdio.h>
#include<string.h>
#include<math.h>
long long int N;
char b[20];
void solve()
{
int k, x, y;
sprintf(b, "%d", N);
for(k = strlen(b) + 1;; k ++)
{
x = (long long int)(log2(N) + k * log2(10));
y = (long long int)(log2(N + 1) + k * log2(10));
if(x != y)
{
printf("%d\n", y);
break;
}
}
}
int main()
{
while(scanf("%lld", &N) == 1)
{
solve();
}
return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值