Search code examples
c++optimizationfactorial

Making a factorial program faster?


I've been trying to submit this to a website with programming lessons, but the judge keeps telling me that this program takes too long to execute :/

Problem Statement:

Write a program that reads a non-negative integer n from the standard input, will count the digit of tens and the digit of ones in the decimal notation of n!, and will write the result to the standard output. In the first line of input there is one integer D (1≤D≤30), denoting the number of cases to be considered. For each case of entry. your program should print exactly two digits on a separate line (separated by a single space): the tens digit and the ones digit of n! in the decimal system.

Input/Output:

Input Output
2
1 0 1
4 2 4
#include <iostream>

using namespace std;

int d,n;

int main()
{
    cin>>d;
    for(int i=0; i<d; i++)
    {
        cin>>n;
        int silnia = 1;
        for(int j=n; j>1; j--)
        {
            silnia=silnia*j;
        }
        if(silnia == 1) cout<<0<<" "<<silnia<<"\n";
        else cout<<(silnia/10)%10<<" "<<silnia%10<<"\n";
    }
    return 0;
}

Solution

  • Since only the last 2 digits of n! are needed, any n >= 10** will have a n! with 00 as the last 2 digits.

    A short-cut is to test n: This takes the problem from O(n) to O(1).

      int factorial = 0;
      if (n < 10) {
        int factorial = 1;
        for(int j=n; j>1; j--)
        {
            factorial *= j;
        }
        factorial %= 100;
      }
    

    Or use a look-up table for n in the [0...10) range to drop the for loop.

    ---
    

    ** 10_or_more! has a 2 * 5 * 10 * other factors in it. All these factorials then end with 00.