博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 701 The Archeologists' Dilemma
阅读量:6842 次
发布时间:2019-06-26

本文共 1299 字,大约阅读时间需要 4 分钟。

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
#include
#include
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; }

转载地址:http://tjzul.baihongyu.com/

你可能感兴趣的文章
年轻时不做会后悔的八件事
查看>>
重读传递参数
查看>>
剖析 Recipe
查看>>
OS X系统启动的基本步骤
查看>>
C Primer Plus 第6章 C控制语句:循环 6.11 使用函数返回值的循环的例子
查看>>
怎么保存退出vi编辑
查看>>
JBoss 系列三十九:jBPM5示例之 Multiple Instance Sub-Process
查看>>
C++面向对象网络编程之SockCli
查看>>
REST概述
查看>>
史上最详细的Android Studio系列教程三--快捷键
查看>>
goclipse 修改输出编译命令,显示完整的错误信息
查看>>
如何提高你的销售业绩
查看>>
中小企业云ERP系统的实施应用特点
查看>>
Memcached在项目中的应用
查看>>
纠结的chm为什么打不开?
查看>>
java list 遍历给javascript数组
查看>>
request 相关请求
查看>>
Product Key Explorer(程序密钥显示工具) v3.9.1官方版
查看>>
网上外卖及订餐系统的数据库设计
查看>>
Navicat Premium 数据传输如何设置
查看>>