标题:二分查找问题求解 我写了一个tle掉了
只看楼主
xiaohuo66
Rank: 1
等 级:新手上路
帖 子:51
专家分:0
注 册:2020-11-1
结帖率:88.89%
已结贴  问题点数:20 回复次数:5 
二分查找问题求解 我写了一个tle掉了
F - F
Problem Description
Printf the smallest x that x^x>10^(n-1)

Input
Multi testcases.

For each testcase:

    a positive integer n (1 <= n <= 1e9)in a line

Output
For each testcase:

    print the answer in a line

Sample Input
5


Sample Output
6
搜索更多相关主题的帖子: 二分 For line 查找 Sample 
2020-11-11 15:42
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:20 
这个数值好大呀

x^x>10^(n-1)
log(x^x) > n-1
x*log(x) > n-1
能用这种方式把数据缩小吗?
2020-11-11 16:48
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
如果可以的话,x 最大值为 123579654,可以二分,或者求导( x^x的导数 = x^x * (ln(x)+1) )
2020-11-11 16:56
xiaohuo66
Rank: 1
等 级:新手上路
帖 子:51
专家分:0
注 册:2020-11-1
得分:0 
回复 2楼 rjsp
好像就是缩小后二分或者求导,但我tle
掉了
2020-11-11 17:09
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
程序代码:
#include <stdio.h>
#include <math.h>

unsigned foo( unsigned n )
{
    // x*ln(x) > (n-1)*ln(10)
    // x*ln(x) 的导数是 1 + ln(x)

    double rhs = (n-1)*log(10.);

    unsigned a=1, b=123579654;
    for( ; a+1!=b; )
    {
        unsigned m = (a+b)/2;
        if( m*log(m+0.) > rhs )
            b = m;
        else
            a = m;
    }
    return b;
}

#include <assert.h>

int main( void )
{
    assert( foo(1) == 2 );
    assert( foo(2) == 3 );
    assert( foo(3) == 4 );
    assert( foo(4) == 5 );
    assert( foo(5) == 6 );
    assert( foo(6) == 7 );
    assert( foo(7) == 8 );
    assert( foo(8) == 8 );
    assert( foo(9) == 9 );
    assert( foo(10) == 10 );
    assert( foo(11) == 11 );
    assert( foo(12) == 11 );
    assert( foo(13) == 12 );
    assert( foo(14) == 13 );
    assert( foo(15) == 13 );
    assert( foo(16) == 14 );
    assert( foo(17) == 14 );
    assert( foo(18) == 15 );

    assert( foo(1000000000) == 123579654 );
}
2020-11-12 10:30
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
如果用 切线法,可以比 二分法 更快。(n从2到123579654,实测二分法共耗时 157 时间单位, 切线法共耗时 96 时间单位)

程序代码:
unsigned foo( unsigned n )
{
    // x*ln(x) > (n-1)*ln(10)
    // x*ln(x) 的导数是 1 + ln(x)

    const double rhs = (n-1)*log(10.);

    for( unsigned x=1; ; )
    {
        double y = x*log(x+0.) - rhs;

        if( y <= 0 )
        {
            double y2 = (x+1)*log(x+1.) - rhs;
            if( y2 > 0 )
                return x+1;
            x = (unsigned)floor( x+1 - y2/(1+log(x+1.)) );
        }
        else
        {
            double y2 = (x-1)*log(x-1.) - rhs;
            if( y2 <= 0 )
                return x;
            x = (unsigned)floor( x-1 - y2/(1+log(x-1.)) );
        }
    }
    return 0;
}
2020-11-13 09:28



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-503863-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.057121 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved