Just the Facts - 1604

Just the Facts
Time Limit: 1000MS
Memory Limit: 65536K
Total Submissions: 9118
Accepted: 4795

Description

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 (0 <= N <= 10000). 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 Output

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

Source

算法描述:
方法一:
由于N!可能非常大,比如10000!形成的结果有35660位,远远超出我们正常long能够保存的数字范围,从而考虑用数组来存储大数的方法,定义一个short a[40000]的数组来存储结果的每一位,比如120,就可以用数组表示为a[0] = 1;a[1] = 2;a[3] = 0等,然后用一个方法来控制并完成计算,但这种方法太耗时间,还是另外采取别的方法比较好。缺点:超时
代码如下:
#include<stdio.h>  
#include<string.h>  
int a[40000];  
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<40000; 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;  
}  



方法二:
此方法体现了数学的技巧,我们对于一个数的阶乘,只关心最后末尾首次不是0的数字,对于高位的数字是多少或者N!具体等于多少并不关心,从而我们可以用/和%的方法对N!进行中途处理,当结果超过一定范围时,比如超过100000时,就对它进行
%100000处理,从而把数的结果变小,而不影响最后5位的值;但是中途会出现末尾为0的情况,万一最后超过5个0怎么办?从而我们再用一个while循环来处理,比如5!=120,中途处理掉后,就成了12,不影响末尾数字的大小,比如12*6=72,而120*6=720,6!末尾首次不是0的数字为2,不影响结果,这就是算法的奥妙。我们总要想尽一切办法把和结果无关的过程处理掉,把相关的数字或者结果提取出来,达到我们想要的目的。

代码如下:

/***********************************************************************
    Copyright (c) 2015,wangzp
    All rights no reserved.
  
    Name: 《Just the Facts》In PEKING UNIVERSITY ACM
    ID:   PROBLEM 1604
    问题简述: 求一个整数N!(0<=N<=10000),然后把末尾首个不是零的数字输出出来。
	算法描述:如果用数组存储大数字的方法,比较简单,但是容易超时。
	          由于题意中不是计算N!具体等于多少,而是要最末尾不是0的数字;
			  从而,我们对于高位的数字并不关心,所以我们可以在用%或者/来
			  控制数字的大小,对结果不会产生影响。
    Date: Oct 10, 2015 
 
***********************************************************************/
#include
   
   
    
      
int main(void)  
{  
	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;  
}  
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值