刚刚做的一道原创算法题,题目简单,做起来难,大家看看有什么想法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lhx2008
V2EX    问与答

刚刚做的一道原创算法题,题目简单,做起来难,大家看看有什么想法

  •  1
     
  •   lhx2008 2018-04-20 21:40:08 +08:00 3193 次点击
    这是一个创建于 2801 天前的主题,其中的信息可能已经有所发展或是发生改变。

    输入:n (1 < n < 10^9)

    从 1 开始到 n,转成字符串,然后拼接在一起

    输出:这个字符串的长度


    比如:

    输入 13

    拼接:12345678910111213

    输出 17


    特别注意:

    时间限制 0.01s 一个数,也就是说不能真的做字符串拼接

    20 条回复    2018-04-21 08:31:56 +08:00
    lhx2008
        1
    lhx2008  
    OP
       2018-04-20 21:42:04 +08:00
    我是花了 40 分钟才做出来,时间复杂度 O(length(n))
    njlcazl
        2
    njlcazl  
       2018-04-20 21:45:25 +08:00 via iPhone
    看着像数位 dp 的题
    orangeade
        3
    orangeade  
       2018-04-20 21:49:19 +08:00 via Android
    对每个数按位数分类,然后统计?
    orangeade
        4
    orangeade  
       2018-04-20 21:55:33 +08:00 via Android   5
    13:9 * 1 + 4 * 2,
    看下 n 的位数,如果是 n=123,就是 9 * 1 + 90 * 2 +(123 - 100 + 1)* 3
    找下规律就行
    Biggoldfish
        5
    Biggoldfish  
       2018-04-20 21:57:41 +08:00
    今天美团的笔试题吧,就是楼上的思路。AC 代码:
    #include <iostream>
    #include <cmath>
    using namespace std;
    int main(){
    int T;
    cin >> T;
    int n = 0, digits = 0;
    long long ans = 0;
    long long pow10 = 0;
    while(T--){
    cin >> n;
    digits = (int)log10(n);
    pow10 = rint(pow(10,digits));
    ans = digits * pow10 + (1 - pow10) / 9;
    ans += (n - pow10 + 1) * (digits + 1);
    cout << ans << endl;
    }
    return 0;
    }
    casparchen
        6
    casparchen  
       2018-04-20 22:00:21 +08:00/span>   7
    有公式啊,O(1)

    ```
    from math import floor, log10
    solve = lambda n: (n+1)*floor(log10(10*n)) - (10**floor(log10(10*n))-1)/9
    ```
    tautcony
        7
    tautcony  
       2018-04-20 22:00:49 +08:00 via Android
    数数题嘛。设数字为 n,len 为 n 的位数,nine 为 len-1 个 9。ans+=len*(n-nine),然后 n=nine 的,重复操作到只剩个位数就好了。
    casparchen
        8
    casparchen  
       2018-04-20 22:02:52 +08:00
    >>>solve(13)
    17
    >>>solve(123456700)
    999999198
    ech0x
        9
    ech0x  
       2018-04-20 22:05:06 +08:00   1
    先将 n 拆分成 n=99....99+m,9 的个数不定,接下去就是数字个数乘以位数 ,这就是个数学问题了。至于位数,我觉得就是这题允许的一个小 trick,转换一个数字到字符串然后获得长度,这个长度就是位数。
    lhx2008
        10
    lhx2008  
    OP
       2018-04-20 22:09:43 +08:00
    @casparchen 这个太强了
    lhx2008
        11
    lhx2008  
    OP
       2018-04-20 22:11:26 +08:00
    @Biggoldfish 是的,是这个搞法
    msg7086
        12
    msg7086  
       2018-04-20 22:29:18 +08:00
    放一个简单点的算法:

    def solve n
      n = n + 1
      digit = 0
      scale = 1
      while scale < n
       digit += n - scale
       scale *= 10
      end
      digit
    end

    solve 13
    # => 17
    solve 123456700
    # => 999999198

    可能比 log10 大法慢一点,但是都是基本运算,比较容易读。
    lhx2008
        13
    lhx2008  
    OP
       2018-04-20 22:46:49 +08:00
    @msg7086 这个写的也很好,是有公式吗
    msg7086
        14
    msg7086  
       2018-04-20 23:46:25 +08:00   4
    @lhx2008
    你这么想,1-9 是一位的,10-99 是两位的,100-999 是三位的。
    所以 solve(123) 的位数就是,个位 1~123 十位 10~123 百位 100~123 再相加。

    也就是
    digit = 0
    digit += 123 - 1 + 1
    digit += 123 - 10 + 1
    digit += 123 - 100 + 1

    转写一下就会变成
    digit = 0; scale = 1
    digit += 123 - scale + 1; scale *= 10
    digit += 123 - scale + 1; scale *= 10
    digit += 123 - scale + 1; scale *= 10

    然后写成循环就好了。
    msg7086
        15
    msg7086  
       2018-04-20 23:53:46 +08:00   1
    这题写成 One liner 也不难的:

    def solve n
    0.upto(9).map{ |scale| [n + 1 - 10 ** scale, 0].max }.sum
    end

    solve 123456700
    # => 999999198
    easylee
        16
    easylee  
       2018-04-21 00:55:48 +08:00
    希望 V 社区多来些这样的面试算法题,还是挺有趣的。
    Bryan0Z
        17
    Bryan0Z  
       2018-04-21 01:54:57 +08:00 via Android
    @msg7086 机智,我刚刚看了代码半天没看懂
    ericls
        18
    ericls  
       2018-04-21 04:53:46 +08:00 via iPhone   1
    这种题有啥意思……
    kifile
        19
    kifile  
       2018-04-21 07:04:35 +08:00   1
    long number=xxxxxxx;
    long length=0;
    while(number>0){
    length+=number;
    number/=10;
    }
    return length;
    pkookp8/td>
        20
    pkookp8  
       2018-04-21 08:31:56 +08:00 via Android
    既然不用拼接,那就是数学题了。。。。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2638 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 89ms UTC 11:50 PVG 19:50 LAX 03:50 JFK 06:50
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86