TOJ1011 阶乘末尾非零数求和

/*

阶乘末尾非零数求和

http://acm.tongji.edu.cn/people/ps/showproblem.php?problem_id=1011

Time Limit:1s Memory Limit:1000k
Total Submit:4671 Accepted:1317

Problem

对于小于25000的自然数n,求阶乘n!,(n-1)!,(n-2)!...3!,2!,1!右边的非零数之和。

例如:

当n=5时,
5!=120,右边非零数为2;
4!=24,右边非零数为4;
3!=6,右边非零数为6;
2!=2,右边非零数为2;
1!=1,右边非零数为1。
其右边的非零数之和为15。

Input

本题有多组数据,每组数据包含一个正整数N(N不大于25000)占一行。

Output

对给定的每组输入数据,输出一个整数。每个结果占一行。不要输出额外的空行。

Sample Input

Sample Output

T_T 超郁闷的题目……

Run ID  User  Problem  Result                   Memory  Time  Language  Date

263600  kingwei  1011  Accepted                   28 k 659 ms C 2005-06-01 16:59:22
263554  kingwei  1011  Time Limit Exceeded              C 2005-06-01 16:03:42
263477  kingwei  1011  Wrong Answer         36 k  10 ms C 2005-06-01 14:37:16
263466  kingwei  1011  Wrong Answer         36 k   6 ms C 2005-06-01 14:28:36
263463  kingwei  1011  Wrong Answer         44 k   6 ms C 2005-06-01 14:27:20 

*/

#include <stdio.h>

#define MAX_NUM 25000
#define MAX_LEN 1600

int start, end;
int workarr[MAX_LEN] = {1, 0};
int res[MAX_NUM] = {0, 1};

int main()
{
 int n, i, j, carry, temp;
 
 start = 0;
 end = 0;
 for (i=2; i<MAX_NUM; i++)
 {
  carry = 0;
  for (j=start; j<=end; j++)
  {
   workarr[j] = workarr[j]*i+carry;
   carry = workarr[j]/10000;
   workarr[j] %= 10000;
  }
  while (carry > 0 && end<MAX_LEN)
  {
   end++;
   workarr[end] = carry%10000;
   carry /= 10000;
    }
  while (workarr[start] == 0)
   start++;
  temp = workarr[start];
  while (temp%10 == 0)
   temp /= 10;
  res[i] = res[i-1]+temp%10;
 }
    
 while (scanf("%d", &n) != EOF)
 {
  printf("%d/n", res[n]);
 }

 return 0;
}

阅读更多
个人分类: 算法相关
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭