AtCoder E - Double Factorial(判断阶乘后面0的个数)

题意
给你一个不小于 0 0 的整数 n n , 然后求 n n 双阶乘的末尾 0 0 的个数。
n ! = n ( n 2 ) ( n 4 ) . . . . . . n!=n*(n-2)*(n-4)......
思路:
我们知道要求阶乘尾部 0 0 的位数:
如果乘积要产生 0 0 的话,那么他们分解的因子中肯定会有 2 5 2*5 ,又因为因子中 2 2 的个数肯定大于 5 5 的个数,所以我们直接考虑 5的位数就是最后0的位数。可写出如下程序:

int main(){
   int n;
   cin>>n;
   int sum = 0;
   while(n){
 	n /= 5;
 	sum += n;    
   }
   cout<<sum;
}

那么这儿是双阶乘,那可怎么办呢?
可以发现,如果 n n 为奇数的时候,一定没有0产生,所以我们只讨论 n n 为偶数的时候。
我这儿有两种方法,本质是一样的,且同我徐徐道来。
O n e : One:
对于 n n 为偶数时,举个例子比如 8 8
f ( 8 ) = 8 6 4 2 f(8)=8*6*4*2
根据上面求阶乘末尾0的个数的思想,我们只关心5的个数。
所以对于上面每一项我们除2得:
f ( 8 ) = 4 3 2 1 = 4 ! f(8)=4*3*2*1=4!
于是我们转化为求 n 2 \dfrac{n}{2}! 的问题。
代码如下:

int main(){
	ll n;
	cin>>n;
	if(n & 1) cout<<0;
	else {
		n /= 2;
		ll sum = 0;
		while(n){
			n /= 5;
			sum += n;
		}
		cout<<sum;
	}
}

T w o Two
求阶乘中0的个数,其实是看阶乘中有多少5。类似的思想:
( N ) N ( N 2 ) ( N 4 ) (N)N(N-2)(N-4) 2能被5整除的次数是(2,4,,N中能被5整除的个数)+ (2,4,,N中能被 5 2 5^2 整除的个数)+ (2,4,,,N中能被 5 3 5^3 整除的个数)。分别是2,4,…, N中可以被5整除的个数是floor(N/10), 2,4, ., N中可以被 5 2 5^2 整除的个数是floor(N/50), 2,4, ., N中可以被 5 3 5^3 整除的个数是floor(N/250),…因此,从N/10开始,分母在N以下之间,分母增加5倍求商,这样反复进行,取其总和即可。
这种方法可能不如上面那么直观。
A C   C o d e : AC \ Code:

int main(){
	ll n;
	cin>>n;
	if(n & 1) cout<<0;
	else {
		ll sum = 0;
		ll x = n;
		
		for(ll t = 10;(x/t)!=0;t *= 5){
			sum += x/t;
		}
		cout<<sum;
	}
}
发布了632 篇原创文章 · 获赞 27 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_43408238/article/details/103666410
今日推荐