UVA 568 Just the Facts (阶乘)

题意:求一个数n的阶乘,其往后数第1个不是0的数字是多少。

思路:[1,n]逐个乘,出现后缀0就过滤掉,比如12300就变成123,继续算下去。为解决爆long long问题,将其余一个数mod,过滤掉前面过大的部分,因为计算出来也没用。这个mod应该是多少? 10亿就行。

 1 #include <bits/stdc++.h>
 2 #define LL long long
 3 using namespace std;
 4 const int N=10001;
 5 const int mod=1000000000;
 6 int ans[N];
 7
 8 void init()
 9 {
10     LL fun=1;
11     ans[1]=1;
12     for(int i=2; i<N; i++)
13     {
14         fun*=i;
15         while(fun%10==0)
16             fun/=10;    //过滤掉后缀0
17         ans[i]=fun%10;          //取最后一位
18         fun%=mod;
19     }
20 }
21
22 int main()
23 {
24     //freopen("input.txt", "r", stdin);
25     init();
26     int a;
27     while(~scanf("%d",&a))
28         printf("%5d -> %d\n",a,ans[a]);
29     return 0;
30 }

AC代码

时间: 2024-08-06 16:06:03

UVA 568 Just the Facts (阶乘)的相关文章

UVa 568 Just the Facts

A过去后看了一下别人的解法,发现除了打表还有一种数论的方法. 分析一下阶乘后面的0是怎么出现的呢,当然是2乘5得到的. 我们将1~N先放在一个数组里面. 从数组第一个元素开始,先统计一下N!中因子为5的个数记为count,将其除去,然后再除去count个2.这样一来的话把所有元素乘起来后就不会出现10的倍数了. 当然并不是真正的乘起来,那样的话肯定是要溢出的,因为只关心最后一位数,所以每次乘完后求10的余数即可. 我的做法是打表,因为题目里给了N <= 10000的条件限制,所以可以把1~100

Just the Facts UVA 568

说说:这道题的题意是求出给定的N!(N<=10000)的第一个非零的数.可以想象10000!是非常可怕的,所以我开始的想法是将1~10000的结果都求出来保存在数组中,然后直接调用即可.而求结果的方法是从1开始键乘,且只保存结果的最后非零的两位.因为在很多情况下,第一个非零的数与太后面的数是没什么关系的.按照这个思路测试了一下,发现比较小的数没问题,当N逐渐变大的时候,后面就全乱了.原因应该是暂存的结果再乘以新的N的时候前两位就是0,所以最后的结果其实是与暂存结果的第三位数有关的,因此结果至少要

uva 568(数学)

题解:从1開始乘到n,由于结果仅仅要最后一位.所以每乘完一次,仅仅要保留后5位(少了值会不准确,刚開始仅仅保留了一位.结果到15就错了,保留多了int会溢出,比方3125就会出错) 和下一个数相乘,接着保留5位,注意5位没有后导零,最后取5位中最后一个不是零的就能够了. #include <iostream> #include <cstdio> using namespace std; int main() { int n; long int temp; while (scanf(

UVA题目分类

题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics 10300 - Ecological Premium 458 - The Decoder 494 - Kindergarten Counting Game 414 - Machined Surfaces 490 - Rotating Sentences 445 - Marvelous Mazes

《刘汝佳算法竞赛入门经典》第五章 数论

Skew Binary 斜二进制 斜二进制的每位为0, 或 1, 最低位可以为2. 第k位的...代表 2k+1 -1,给出一个斜二进制数,把他转换成十进制数.正常模拟就好 1 #include <cstdio> 2 #include <cstring> 3 char A[1000]; 4 5 int main() { 6 while (scanf("%s", A) != EOF) { 7 if (A[0] == '0') break; 8 int len =

UVA 10061 How many zero&#39;s and how many digits ? (m进制,阶乘位数,阶乘后缀0)

题意:给出两个数字a和b,求a的阶乘转换成b进制后,输出(1)后缀中有多少个连续的0? (2)有多少位? 思路:逐个问题解决. 设a!=k.  k暂时不用直接转成b进制. (1)阶乘后缀0问题.先看这个十进制后缀0的例子:http://www.cnblogs.com/xcw0754/p/4604473.html 解法差不多,稍变化. 首先将b分解成若干质数(比如8={2*2*2})保存在一个集合A中(注意自然数的质数分解是唯一的),只要有一个序列A就能构成一个0,因为满b就进位,b可以表示成10

UVa 10007 - Count the Trees(卡特兰数+阶乘+大数)

题目链接:UVa 10007 题意:统计n个节点的二叉树的个数 1个节点形成的二叉树的形状个数为:1 2个节点形成的二叉树的形状个数为:2 3个节点形成的二叉树的形状个数为:5 4个节点形成的二叉树的形状个数为:14 5个节点形成的二叉树的形状个数为:42 把n个节点对号入座有n!种情况 所以有n个节点的形成的二叉树的总数是:卡特兰数F[n]*n! 程序: 1 import java.math.BigInteger; 2 import java.util.Scanner; 3 public cl

UVA 10780

Problem 给两个整数M,N,要求找到最小的正整数K,使得(M^k)可整除(N ! ).输出K,若不存在,输出不存在. Limits Time Limit(ms): 3000 Memory Limit(MB): No Limit M: [2, 5000] N: [1, 10000] 不超过500个case Solution 分解素因数,将M表示成(Pi1^Ki1)*(Pi2^Ki2)*......*(Pin^Kin) ,再将 N ! 表示成 (Pj1^Kj1)*(Pj2^Kj2)*.....

poj 1604 Just the Facts

Just the Facts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8781   Accepted: 4659 Description The expression N!, read as "N factorial," denotes the product of the first N positive integers, where N is nonnegative. So, for example