The Last Non-zero Digit

题意

题目链接
本题大意为 给定m,n

求: P n m P^m_n Pnm的最后一位非0的数

(P在排列组合中就相当于A)

(beican)历程

看到题目 什么都不会的我一脸懵

洛谷的限制太水了

vjudge上时限1s

我们按严格的来)

但仔细想了一下 我仍然只发现暴力是不可以的

我暴力的思路是 乘起来

但直接乘会爆 就留个9位吧(感觉有点靠运气)

这样的思路肯定是错的 (像这位小哥

也不要想去优化 不然就像我搞了半天 仍然TLE

接着 再仔细想想 发现求最后一位非0的数 只需要我们在算的过程中除10

又知道 P n m P^m_n Pnm = n ! ( n − m ) ! \frac{n!}{(n -m)!} (nm)!n! = ∏ i = n − m + 1 n \prod^n_{i=n-m+1} i=nm+1ni

换言之我们需要将含有因子2和5的除*掉

BTW将因子2和因子5的数量统计

因为一个10是由一个2和一个5乘得得

直接除*掉不能保证因子2与因子5数量相等

需要把多的乘回去(用快速幂)

for(i = n;i > n - m;i--)
	 {
   
	    	int j = i;
	    	while(j % 2 == 0)
	    	{
   
	    		j /= 2;
	    		d2++;
			}
	    	while(j % 5 == 0)
	    	{
   
	    		j /= 5;
	    		d5++;
			}
			
			ans = (ans * j) % 10;
		}
if(d2 > d5)
			More = qkpow(2,d2 - d5);
		else if(d5 > d2) More = qkpow(5,d5 - d2);

整体的代码大致如下

#include <cstdio>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
 
using namespace std;

long long d2,d5,More,ans;
inline long long qkpow(int val,int n)
{
   
	long long rest = 1;
	while(n)
	{
   
		if(n & 1)
			rest = val * rest % 10;
		val = val * val % 10;
		n >>= 1;
	}
	return rest;
}
int main()
{
   
    int i,n,m;
    while(~scanf("%d%d",&n,&m))
    {
   
    	d2 = d5 = 0;
    	More = ans = 1;
	    for(i = n;i > n - m;i--)
	    {
   
	    	int j = i;
	    	while(j % 2 == 0)
	    	{
   
	    		j /= 2;
	    		d2++;
		
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值