zzuli 2184 河南多校联萌(5)(非二分)
来源:互联网 发布:90后听的经典网络歌曲 编辑:程序博客网 时间:2024/05/01 21:44
Description
每一个数都有若干个后缀零,比如100有2个、10有1个、1有0个,那么问题来了,已知整数n,求x使其满足x!的后缀零个数为n
Input
输入一个数T (≤ 10000),表示有T组数据
接下来T行每一行有一个数n (1 ≤ n≤10^8)
Output
每组数据首先输出当前组数(格式参见Sample Output),之后输出满足情况时最小的x,如果x不存在,输出no
Sample Input
3
1
2
5
Sample Output
Case 1: 5
Case 2: 10
Case 3: no
题意很简单 ,给一个n求一个最小的x,使x满足x!的后缀零个数为n;找不到输出no
想要在乘法中产生0,要么乘以一个后缀零不为0的数,要么乘以一个5的倍数,细想一下,后缀零不为0的数 一定是5的倍数,所以 只要题目就是求 一个最小的x使x!中5的因子个数;
首先最容易想到的从5开始5个数5个数的加,循环遍历,直到5的因子个数达到n,但是这样写肯定超时。
标程是用二分,可以解。
这里我给出一个非二分的解题方法;本质仍然是暴力;
思路:上面说一次+5暴力循环会超时,那么就想到如果一次+25/125/625/3125是否可行?
如果题读懂很容易能想到一个东西,从1开始每5个数的积5的因子个数是1(小于25的情况下),eg:1-5的积5的因子个数是1,5-10的积5的因子个数是1…
每25个数的积5的因子个数是6(小于125的情况下),eg:1-25的积5的因子个数是6,26-50的积5的因子个数是6….,这个很好算,拿1-25举例,1-25可以分成5组,有4组的积5的因子个数是1,含25的那一组因为25这个数特殊 这一组的积5的因子个数是2;
往下递推 可以得出
1开始每5个数的积5的因子个数是1(小于25的情况下)
每25个数的积5的因子个数是6(小于125的情况下)
每125个数的积5的因子个数是31(小于625的情况下)
每625个数的积5的因子个数是156(小于3125的情况下)
这样可以事先存两个数组;
int a[100],b[100]; a[0]=1; b[0]=5; for(int i=1;i<=15;i++) { b[i]=b[i-1]*5; a[i]=a[i-1]*5+1; }
这两个数组的含义是:eg:b[2]=125,a[2]=156;代表每125个数可以提供31个后缀零;
之后就是暴力了 eg:n=400的时候
首先一个循环在a数组内找到n在哪个位置
int flag=0; for(int i=1;i<=15;i++) { if(n<=a[i]) { flag=i-1; break; } }
得出flag=3,说明a[4],b[4]所代表的每3125个数可以提供780个后缀零太多,不能一次+a[4]=3125,只能一次+625;
下面是一个while循环
1.看看可以+几个625,即int ans1=n/a[flag];
2.设一个ans变量 记录目前为止有多少个后缀零了, ans+=ans1*a[flag];
3.设一个sum变量记录目前加到哪个数了, sum+=ans1*b[flag];
4.更新n的值n-=ans1*a[flag];
5.判断如果正好能够加5次 即ans==5的时候 ans要再+1,(想不明白参照上面 “每25个数的积5的因子个数是6”那一段)
6.如果ans<所需要的后缀零的个数,flag–返回第1步;
以n=400为例 手动模拟上述过程:
1.ans1=400/156=2;
2.ans+=2*156=312;
3.sum+=2*625=1250;
4.n=400-2*156=88;
5.ans1==2 不加
6.ans=312<400 flag– 返回第一步
1.ans1=88/31=2;
2.ans+=2*31=374;
3.sum+=2*125=1500;
4.n=88-2*31=26;
5.ans1==2 不加
6.ans=374<400 flag– 返回第一步
1.ans1=26/6=4;
2.ans+=4*6=398;
3.sum+=4*25=1600;
4.n=22-4*6=2;
5.ans1==4 不加
6.ans=398<400 flag– 返回第一步
1.ans1=2/1=2;
2.ans+=2*1=400;
3.sum+=2*5=1610;
4.n=2-2*1=0;
5.ans1==2 不加
6.ans=400==400 跳出
最后再判断如果ans>400 输出no
否则输出 sum
全代码
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>using namespace std;int main(){ int a[100],b[100]; a[0]=1; b[0]=5; for(int i=1;i<=15;i++) { b[i]=b[i-1]*5; a[i]=a[i-1]*5+1; } int n,t; scanf("%d",&t); int e=0; while(t--) { e++; scanf("%d",&n); int flag=0; for(int i=1;i<=15;i++) { if(n<=a[i]) { flag=i-1; break; } } int sum=0; int ans=0; int d=n; while(ans<d) { int ans1=n/a[flag]; ans+=a[flag]*ans1; sum+=ans1*b[flag]; n-=ans1*a[flag]; if(ans1==5) ans++; flag--; } if(ans>d) printf("Case %d: no\n",e); else printf("Case %d: %d\n",e,sum); } return 0;}
- zzuli 2184 河南多校联萌(5)(非二分)
- zzuli 1919(二分)
- 【zzuli-oj】-1918-寻宝(二分图,坑)
- 【zzuli-oj】-1917-定义序列价值(二分 & STL,好)
- zzuli 1895: 985的0-1串难题(二分)
- zzuli oj 多校训练(三)【树链剖分--树状数组---STL----二分图----二分----DP】
- GJJ来签到 (河南多校联萌 四 )
- zzuli 1893(二进制)
- zzuli 1922 (棋盘)
- 二分查找(非递归)
- 二分排序(非递归)
- 二分查找(非递归)
- ZZuli oj 1895: 985的0-1串难题(二分+打表)
- ZZULI-1912 小火山的爱情密码 【尺取(OR 二分)+map】
- zzuli 1912: 小火山的爱情密码(二分 || 尺取)
- ZZULI OJ 1918: G (宝塔寻宝,二分图最大匹配)
- 【zzuli】-音痴又音痴的LT(STL& 二分)
- ZZULI-oj-1919(二分)
- 价格标
- vim基本命令的使用
- C++文件操作——查找某一类文件的三种方法
- 1.6 数组
- 2017年8月26日,周结(二十三),PopupWindow的简单使用
- zzuli 2184 河南多校联萌(5)(非二分)
- RabbitMQ消息队列之一:RabbitMQ的环境安装及配置
- FATAL ERROR: please install the following Perl modules before executing
- 正则表达式详解
- bootstrap table通过ajax获取后台数据展示在table
- python练习题
- 再起航,我的学习笔记之JavaScript设计模式12(适配器模式)
- 2017 8.25 阿里巴巴校招 在线笔试题
- 深入浅出C#(C#指南)