Factorial
2015-08-21 18:24
232 查看
You task is to find minimal natural number N, so that N! contains exactly Q zeroes on the trail in decimal notation. As you know N! = 1*2*...*N. For example, 5! = 120, 120 contains one zero on the trail.
One number Q written in the input (0<=Q<=10^8).
Write "No solution", if there is no such number N, and N otherwise.
Sample test(s)
Input
2
Output
10
解题报告:
原来做过这样一个题,求n!末尾有几个0,先要把这个题搞懂。在n!要把每个数拆分成质因数的积,N!=2^a*3^b*5^c*7^d........因为只有2*5 才会出现 0,所以质因数有多少5,尾部就有多少个0,且2的个数会比5多很多,所以只要求5的个数即可。有一个公式:
设f(n)为n!末尾0的个数,则
0(0<n<5)
f(n!)=
k+f(k!)(k=n/5)
有了这个公式之后,关键代码就为:
while(n)
{
n/=5;
i+=n;
}
最后输出i的值即可。
同样,这个题
Q = N/5 + N/(5^2) + N/(5^3) + ...
由等比数列求和可得(设只到前k项):
Q = N(5^k - 1) / [4*(5^k)],由此得:
N = 4Q * [(5^k)/(5^k-1)]
注意:当Q为0时要输出1
这个题也可以用二分算:
Input
One number Q written in the input (0<=Q<=10^8).
Output
Write "No solution", if there is no such number N, and N otherwise.
Sample Input
Sample test(s)Input
2
Output
10
解题报告:
原来做过这样一个题,求n!末尾有几个0,先要把这个题搞懂。在n!要把每个数拆分成质因数的积,N!=2^a*3^b*5^c*7^d........因为只有2*5 才会出现 0,所以质因数有多少5,尾部就有多少个0,且2的个数会比5多很多,所以只要求5的个数即可。有一个公式:
设f(n)为n!末尾0的个数,则
0(0<n<5)
f(n!)=
k+f(k!)(k=n/5)
有了这个公式之后,关键代码就为:
while(n)
{
n/=5;
i+=n;
}
最后输出i的值即可。
同样,这个题
Q = N/5 + N/(5^2) + N/(5^3) + ...
由等比数列求和可得(设只到前k项):
Q = N(5^k - 1) / [4*(5^k)],由此得:
N = 4Q * [(5^k)/(5^k-1)]
注意:当Q为0时要输出1
#include <cstdio> #include <cstring> using namespace std; int fun(int x) { //求x尾部有多少个0 int sum = 0; while(x) { sum += x / 5; x /= 5; } return sum; } int main() { int Q; while(scanf("%d", &Q) != EOF) { if(Q == 0) { printf("1\n"); continue; } int N = Q * 4 / 5 * 5; //依据公式先大致算到4*Q(除5乘5是为了N正好是5的倍数),然后再往后推 while(fun(N) < Q) { N += 5; } if(fun(N) == Q) printf("%d\n", N); else printf("No solution\n"); } return 0; }
这个题也可以用二分算:
#include<iostream> #include<string.h> #include<stdio.h> #include<ctype.h> #include<algorithm> #include<stack> #include<queue> #include<set> #include<math.h> #include<vector> #include<map> #include<deque> #include<list> #define N 0x7fffffff using namespace std; int num0(int n) { int count=0; while(n) { count+=n/5; n/=5; } return count; } void find(int w) { int left=0,right=N,mid; while(left<=right) { mid=(left+right)>>1;//位运算速度快 // mid=(left+right)/2; if(num0(mid)>=w) right=mid-1; else left=mid+1; } if(num0(left)==w) printf("%d\n",left); else puts("No solution"); } int main() { int n; while(scanf("%d",&n)!=EOF) { if(n==0) printf("1\n"); else { find(n); } } return 0; }
相关文章推荐
- 【写一个自己的js库】 1.搭个架子先
- 遇到的几个关于路径报错的问题
- 页面加载时弹出alert对话框
- unity3D中脚本生命周期
- 【日常】在某特定条件下提权夺取服务器权限
- 九度oj 1119
- android Listview,gridview局部刷新,部分刷新
- day7: 类的扩展 NSDate NSDateFormatter Category Extension延展 Protocol协议 delegate代理
- c++学习笔记(三)多态性
- Mysql Linux数据目录变更迁移
- Fragment使用带参数的构造函数遇到的问题
- BZOJ 3550 [ONTAK2010]Vacation 线性规划
- 最大公约数——Program G
- ODOO8 Sale模块实施的按钮权限更改
- 畅通工程续(2008浙大研究生复试热身赛[最短路径] hdoj 1874)
- bzoj-1467 clever Y / JDFZ-2940 EXBSGS
- 用Chrome devTools 调试Android手机app中的web页面。
- 【shell脚本练习】判断用户存在和用户类型
- jar包运行
- 【shell脚本练习】判断用户存在和用户类型