Algorithm for 'good' number

后端 未结 3 1687
梦毁少年i
梦毁少年i 2021-01-29 07:02

A give number x is \'good\' if the sum of any two consecutive digit of the number x are between k and 2k. I need to find an algorithm that for a given number k and a given numbe

相关标签:
3条回答
  • 2021-01-29 07:14

    Your algorithm counts how many 2 digit integers are NOT good. Then it returns this value to the power of n - 1. This should get you the number of n digit numbers that are NOT good. If you subtract this value from the total amount of n digit integers, you should get what you want. Or we could avoid doing this by changing the signs:

    for($i=10; $i<100; $i++) {
     if( ($i/10) + ($i%10) > $k && ($i/10) + ($i%10) < 2*$k ) {
      $cnt++;
     }
    }
    $result = pow($cnt, $n-1);
    

    This should get you the number of good n digit integers, but let's see if that's really the case.

    Well, cnt will give the number of good 2 digit integers. So, on the first two positions, we can put any of these cnt:

    0 1 2 3 4 5 ...
    x y
    

    Then, what about positions 1 and 2? Well, position 1 is fixed by the first placement.

    0 1 2 3 4 5 ...
    x y
      y z
    

    So we have to prove that there are cnt possibilities for z, and I don't see why this should be the case, so I would say that the algorithm is wrong. Your algorithm will probably overcount.

    0 讨论(0)
  • 2021-01-29 07:16

    All those calls to pow certainly won't be helping.

    What you can do is make a mapping of all the two-digit numbers that are 'good'. Once you have your mapping, all you need to do is check that every pair of digits in your number is good. You can do this by successive division by 10 and modulo 100.

    Something like this would do the trick, provided you don't give it a negative number, and assuming you've set up your $good array.

    function isgood( $num ) {
        while( $num >= 100 && $good[$num%100] ) {
            $num /= 10;
        }
        return $good[$num%100];
    }
    

    The next most obvious thing to do is memoize larger sequences. This is a dynamic programming principle. We've already memoized small sequences by storing the 'goodness' of 2-digit sequences. But you could easily use those to generate sequences of 3, 4, 5, 6 digits... Whatever your available memory allows. Use the memos you already have in order to generate the sequences with one extra digit.

    So, if you built up memoisation for up to 5-digit numbers, then you divide by 1000 every time, and get a great speedup.

    0 讨论(0)
  • 2021-01-29 07:19

    Finding the number of "not good numbers" with n digits and top digit d is a straightforward dynamic programming problem.

    10^n is the number of "good numbers" plus "not good numbers".

    I will give you no more help than that.

    0 讨论(0)
提交回复
热议问题