算法训练 P0505

P0505

n!=1234.......(n-1)n, n!末尾的0的是由因子2和5造成的。
可以这么想,先将1到n每个数做关于2和5的因数分解,其实想法十分简单就是在计算阶乘时将所有因数2和5都不乘进去。而是用a,b分别记录2的个数和5的个数。
ans记录的是n!末尾非零的数字,初始化ans=1。

#include<iostream>
#include<math.h>
using namespace std;
int a=0, b=0;
int main(){
	long long int n, ans=1, t;
	cin>>n;
	for(int i=1; i<=n; i++){
		t=i;
		while(t%2==0){ //将t中的2全部剔除掉,并把含有2因子的个数加到b上
			a++;
			t/=2;
		}
		while(t%5==0){ //将t中的5全部剔除掉,并把含有5因子的个数加到b上
			b++;
			t/=5;
		}
		if(t!=0)
			ans*=t;
		ans=ans%10; //保证ans记录的是一个个位数,是n!的最后一个非零的数
	}
	if(a>b){ //2的个数比5多
		switch((a-b)%4){ //只需要考虑比5多出来的2就好了,而2,4,8,16,32,64,......发现其末位数字具有周期性
			case 0: ans=ans*6; break;
			case 1: ans=ans*2; break;
			case 2: ans=ans*4; break;
			case 3: ans=ans*8; break;
			default: break;
		}
	}else if(b>a) //处理多出来5,不管多出来多少个5,它们的乘积个位数都是5.
		ans*=5;
	ans=ans%10;
	cout<<ans<<endl;
	return 0;
} 
原文地址:https://www.cnblogs.com/A-Little-Nut/p/10360413.html