Блог пользователя Nakochi

Автор Nakochi, 13 лет назад, По-английски

Time Limit: 3000ms Memory Limit: 65536kb Description Now, you are given three positive A, B, C, your task is to compute the first B digits and the last C digits of the factorial of A. For example A=5, B=2, C=1. Then A! =120, so you should output 12 0 separated by one blank. Input The first line, an integer T, representing T test cases below. (T<=200). Each test case contains three integers: A (1<=A<=10^8), B (1<=B<=50) and C (1<=C<=100). Notice: No illegal case is permitted. For example, the condition A=4, B=10, C=10 is not permitted in the input data. Output For each case, output the first B digits and the last C digits of the factorial of A separated by one blank. Sample Input 2 5 2 1 8 2 2 Sample Output 12 0 40 20

I've no idea about calculating the first B digits of the factorial. Please help.Thank you. If you want to submit your code , here is the link. http://acm.ustc.edu.cn/ustcoj/problem.php?id=1265 Anybody interested?

  • Проголосовать: нравится
  • +16
  • Проголосовать: не нравится

»
13 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +1 Проголосовать: не нравится

Some interesting fact about last digits: if A>=405 answer will be all zeroes.
And for the first digits there should be sublinear algo.

»
13 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

Have you tried this method?

»
13 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +1 Проголосовать: не нравится

H-m-m, I don't believe that Stirling's approximation is accurate enough to get 100 decimal digits.

What about such combination of stupid ideas:

1) Calculate only 2*B or 1.5*B eldest digits and forget all smaller, hoping that rounding error will not be very large

2) Pre-calc and store results for different A, with step, for example, 10^5, or even 10^4. (How large is source file size limit?)

?

»
13 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +2 Проголосовать: не нравится

About the first B digits, the problem has something same to this problems in hackerrank. The solution is to calculate the first k digits of x, we calculate log10(round(x/10^k)). => Editoral of it. The function can be calculate easily if we can calculate log(n!) in O(1) or O(log(n)). About calculate log(n!) you can see here.

»
13 лет назад, скрыть # |
Rev. 3  
Проголосовать: нравится +9 Проголосовать: не нравится

You can calculate first digits using prime numbers wiki. There is about 5761455 prime numbers less than 10^8. Use Sieve of Eratosthenes to construct them in one second. Don't forget to use long arithmetics. I think first 500 digits is enough to keep to calculate correctly first 400 digits. To make your solution faster on the testing server you can precompute intermediate multiplication results for n = k, k * 2, k * 3 .... for some fixed K, e.g. k = 100000.

»
13 лет назад, скрыть # |
 
Проголосовать: нравится +9 Проголосовать: не нравится

The constraints on B is (1<=B<=50). Why theme title says about 400 first digits?

  • »
    »
    13 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +3 Проголосовать: не нравится

    Sorry, it should be 50, my mistake. What do you mean by "using prime numbers"? --Counting how many times a prime number appears in N! for every prime,and use long arithmetics to multiple them up,and everytime just save first 100 digits(as you point out, B <= 50,100 is enough)? And thank you.

»
13 лет назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

I think the last 100 digits can compute by make a list ,because while N>1000,all the last digits is 0. And the first B digits ,may I use the first B digits to compute?Such as,A=8,B=2,C=1,1*2*3*4=24,then use the first B digis to factory,24*5=120->12,12*6=72->72,72*7=504->50,50*8=400->40 I have not try ,I not sure it is an enable method!!! I hope more acmer provide more and better method.

  • »
    »
    13 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    Seems to be very harsh roundation, so we loose precision. For ex. A=8, B=1:
    1*2*3=6, 6*4=2(4), 2*5=1(0), 1*6=6, 6*7=4(2), 4*8=3(2). So we have contradiction between your and my examples — 8! must be starting with 40 and 3.

»
13 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Using HolyInq`s idea, you can use BigInteger to compute the factorial of A, always taking the remainder by 10**C. It will reach zero in not so much iterations, and you can break if it happens.

Getting the first digits is the toughest part, and I am still not sure of how is the best way to achieve that. I found a lot of ideas on this page and I suggest you take a look on the 100 digits challenge, maybe it helps you: http://www.luschny.de/math/factorial/approx/SimpleCases.html

I am sorry I do not have a very good idea to solve the second part yet...