程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVA 568 - Just the Facts

UVA 568 - Just the Facts

編輯:C++入門知識

Just the Facts
The expression N!, read as ``N factorial," denotes the product of the first N positive integers, where N is nonnegative. So, for example,

N N!
0 1
1 1
2 2
3 6
4 24
5 120
10 3628800

For this problem, you are to write a program that can compute the last non-zero digit of any factorial for (). For example, if your program is asked to compute the last nonzero digit of 5!, your program should produce ``2" because 5! = 120, and 2 is the last nonzero digit of 120.


Input
Input to the program is a series of nonnegative integers not exceeding 10000, each on its own line with no other letters, digits or spaces. For each integer N, you should read the value and compute the last nonzero digit of N!.

Output
For each integer input, the program should print exactly one line of output. Each line of output should contain the value N, right-justified in columns 1 through 5 with leading blanks, not leading zeroes. Columns 6 - 9 must contain `` -> " (space hyphen greater space). Column 10 must contain the single last non-zero digit of N!.

Sample Input
1
2
26
125
3125
9999

Sample Input
1
2
26
125
3125
9999


Sample Output
    1 -> 1
    2 -> 2
   26 -> 4
  125 -> 8
 3125 -> 2
 9999 -> 8

 

看到這個題的第一想法就是用求大數階乘的方法求出n的階乘,然後從最後一位開始找,直到找到一個非零的數輸出。

 

#include<stdio.h>
#include<string.h>
int a[30000];
int main()
{
    int n,i,j,c,s;
    while(~scanf("%d",&n))
    {
		memset(a,0,sizeof(a));
        a[0]=1;
        for(i=2;i<=n;i++)
        {
            s=0;
            for(j=0;j<30000;j++)
            {
                c=a[j]*i+s;
                a[j]=c%10;
                s=c/10;
            }
        }
        for(i=0;;i++)
          if(a[i])
          {
              printf("%5d -> %d\n",n,a[i]);
              break;
          }
	}
    return 0;
}

提交以後是Time limit exceed!

 


後來看了大牛的代碼,才知道自己懂得太少了。下面是一種比較容易理解的代碼:

 include<stdio.h>  
int main() 
{ 
int n,s,i; 
while(scanf("%d",&n)==1) 
{ 
   for(i=1,s=1;i<=n;i++) 
   { 
    s*=i; 
    while(s%10==0) 
     s/=10; 
    s=s%100000; 
   } 
   printf("%5d -> %d\n",n,s%10); 
} 
return 0; 
} 

#include<stdio.h>
int main()
{
int n,s,i;
while(scanf("%d",&n)==1)
{
   for(i=1,s=1;i<=n;i++)
   {
    s*=i;
    while(s%10==0)
     s/=10;
    s=s%100000;
   }
   printf("%5d -> %d\n",n,s%10);
}
return 0;
}

另外讓大家看一下大牛們的代碼:

代碼一:


 

include<stdio.h>  
int main() 
{ 
   int n,i,num; 
   while(scanf("%d",&n)!=EOF) 
   { 
      num=1; 
      for(i=1;i<=n;i++) 
      { 
        if(i%5==0) 
        { 
           int x=i; 
           while(x%10==0) 
              x/=10; 
           while(x%5==0) 
           { 
              x/=5; 
              num/=2; 
           } 
           num*=x; 
         } 
         else 
            num*=i; 
         num%=100000;/

/一定要至少保留後五位非零位(五位以上要注意int型溢出,因此取五位最佳),因為後五位非零位的進位(極限情況3125,即5^5)會影響到最後的非零位  
    } 
   printf("%5d -> %d\n",n,num%10); 
 } 
return 0; 

#include<stdio.h>
int main()
{
   int n,i,num;
   while(scanf("%d",&n)!=EOF)
   {
      num=1;
      for(i=1;i<=n;i++)
      {
        if(i%5==0)
        {
           int x=i;
           while(x%10==0)
              x/=10;
           while(x%5==0)
           {
              x/=5;
              num/=2;
           }
           num*=x;
         }
         else
            num*=i;
         num%=100000;//一定要至少保留後五位非零位(五位以上要注意int型溢出,因此取五位最佳),因為後五位非零位的進位(極限情況3125,即5^5)會影響到最後的非零位
    }
   printf("%5d -> %d\n",n,num%10);
 }
return 0;
}
代碼二:


 

[ include <stdio.h>  
int main() 
{ 
    int n2, n5, i, j, n, digit; 
    while(scanf("%d",&n)!=EOF) 
    { 
         digit = 1; 
         n2 = n5 = 0; 
         for(i=2; i<=n; i++) 
         { 
            j = i; 
            while(j%2 == 0) 
            { 
                n2++; 
                j /= 2; 
            } 
            while(j%5 == 0) 
            { 
                n5++; 
                j /= 5; 
            } 
            digit = (digit * j) % 10; 
         } 
         for(i=0; i<n2-n5; i++) 
            digit = (digit * 2) % 10; 
         printf("%5d -> %d\n",n,digit); 
      } 
    return 0; 
} 

#include <stdio.h>
int main()
{
    int n2, n5, i, j, n, digit;
    while(scanf("%d",&n)!=EOF)
    {
         digit = 1;
         n2 = n5 = 0;
         for(i=2; i<=n; i++)
         {
            j = i;
            while(j%2 == 0)
            {
                n2++;
                j /= 2;
            }
            while(j%5 == 0)
            {
                n5++;
                j /= 5;
            }
            digit = (digit * j) % 10;
         }
         for(i=0; i<n2-n5; i++)
            digit = (digit * 2) % 10;
         printf("%5d -> %d\n",n,digit);
      }
    return 0;

}從2到n,每次更新digit,都先求出該數的2和5的個數,每對2和5相互抵消,每次計算都對10取模,減小計算量。顯然2的個數一定比5的個數多。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved