LightOJ _1138(二分查找)

Time Limit:2000MS    Memory Limit:32768KB    64bit IO Format:%lld & %llu
Submit Status Practice LightOJ 1138

Description

You task is to find minimal natural number N, so that N! contains exactly Q zeroes on the trail in decimal notation. As you knowN! = 1*2*...*N. For example, 5! = 120, 120 contains one zero on the trail.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case contains an integer Q (1 ≤ Q ≤ 108) in a line.

Output

For each case, print the case number and N. If no solution is found then print 'impossible'.

Sample Input

3

1

2

5

Sample Output

Case 1: 5

Case 2: 10

Case 3: impossible

思路分析:刚开始以为只要N!里每出现一个5的倍数,结果的末尾就会多一个0.所以若结尾有n个0,N 的最小值是5n,后来发现错了,如25和4的积有2个0,125和8 的积有3个0。

  5                10               15              25             35                 75                125
 5*1             5*2            5*3            5*5              5*7              5*5*3           5*5*5   (5的个数和下面0的最多个数相等) 
5*2=10    10*2=20    15*2=30   25*4=100   35*4=140    75*4=300    125*8=1000 

 5!          5                                              0 
10!       5、10                                       00
15!       5、10、15                               000
20!       5、10、15、20                      0000
25!       5、10、15、20、25              000000
27!       5、10、15、20、25              000000

My  solution:

/*2015.9.18*/

#include<stdio.h>
int tongji5(int x)/*求1—x数字中5的个数*/
{
	int k,ans=0;
	while(x)
	{
		ans+=x/5;
		x=x/5;
	}
	return ans;
}
int fun(int a)
{
	int i,path,low=5,high=500000000;/*N!的结尾最多有1*10^8个0,因而high=500000000足够了。*/
	while(low<=high)
	{
		path=(low+high)/2;
		if(tongji5(path)>a)
		high=path-1;
		else
		low=path+1;
	}
	high-=high%5;/*转化,当前求得的high值,不是题目所要求的(满足限制条件:0的个数)最小数字*/ 
	if(tongji5(high)==a) 
	return high;          
/*
   high: 从较大数递减进行查找满足题目要求的数字,因而查找到的是满足题目要求(满足限制条件:0的个数)的最大数字.
   low: 从较小数递增进行查找满足题目要求的数字,因而查找到的是满足题目要求(满足限制条件:0的个数)的最小数字.
上面的代码等效于: 
	while(low<=high)                               0的个数      1        2       3       4         6
	{                                
		path=(low+high)/2;             求得相应的数字 high      9       14      19      24        29
		if(tongji5(path)>=a)
		high=path-1;                   求得相应的数字 low       5       10      15      20        25
		else
		low=path+1;
	}
	if(tongji5(low)==a)
	return low;
*/ 
	else
	return 0;	
}
int main()
{
	int i=0,n,t,k;
	scanf("%d",&n);
	while(n--)  
	{
		i++;
		scanf("%d",&t);
		k=fun(t);
		if(k==0)
		printf("Case %d: impossible\n",i);
		else
		printf("Case %d: %d\n",i,k);
	}
	return 0;
}
 
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值