欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LintCode 第二题 坑爹的尾部的零

程序员文章站 2022-03-24 17:41:26
...

设计一个算法,计算出n阶乘中尾部零的个数

样例

11! = 39916800,因此应该返回 2。

起初认为是个很简单的题 后来发现 给的代码区域是这样的。

LintCode 第二题 坑爹的尾部的零

是的 你没看错 就是long long  所以存起来阶乘得数sum*= 是不可能的。

下意识的  想到了只存最后一个数

#include<iostream>
using namespace std;
long long trailingZeros(long long n) {
       		int flag=0; int a=1,b=5;
	   for(long long i=1;i<=n;i++)
       	{
       		if((a*(i%10))%10==0)
       			{
       				
       				/*if(i%5==0)
       					{
       						while(i%b==0)
       							{
       								flag++;
       								b=b*b;
       							}
       						b=5;
       					continue;
       					}*/
       					flag++;
       				if(i%10!=0)a=(a*(i%10))/10%10;
       					else 
       						{       
							   		a=i;							
       							while(a%10==0)
       								{
       									a=a/10;
       								}
       								a=a%10;
       								//acout<<i<<"*"<<a<<" ";
       						}
       			}
       		else 
       			{
       				a=(a*(i%10))%10;
       			}
       		cout<<i<<"*a="<<a<<"flag="<<flag<<endl;
       	}
       return flag;
    }
int main()
{
	long long a;
	cin>>a;
	cout<<trailingZeros(a);
	return 0;
}
测试输出如下 a存的是每次循环乘积的个位数 flag是0的个数
LintCode 第二题 坑爹的尾部的零
两个问题 或者是两个发现:
1. 可以发现i每逢5 flag就多一个
2.flag 在25的时候少了一个  也就是说  25的时候  会出现两个0。(检验后发现的 25的时候正确答案应该是6)

也就是说  0的个数与i的5^n有关系.

深究其原因  我们发现  每一次循环 之后a=5 才有可能与i+1的个位数乘出来一个“0”,而与5相乘的i+1,要么是6,要么是10的倍数 也就是自带一个整数,所以逢5必有0.

而所有25的倍数可以拆分成两个0 125的倍数可以拆分成3个0.
所以在i循环到5的时候做一个判断
#include<iostream>
using namespace std;
long long trailingZeros(long long n) {
       		int flag=0; int a=1,b=5;
	   for(long long i=1;i<=n;i++)
       	{
       		if((a*(i%10))%10==0)
       			{
       				
       				if(i%5==0)
       					{
       						while(i%b==0)
       							{
       								flag++;
       								b=b*b;
       							}
       						b=5;
       					continue;
       					}
       					flag++;
       				if(i%10!=0)a=(a*(i%10))/10%10;
       					else 
       						{       
							   		a=i;							
       							while(a%10==0)
       								{
       									a=a/10;
       								}
       								a=a%10;
       								//acout<<i<<"*"<<a<<" ";
       						}
       			}
       		else 
       			{
       				a=(a*(i%10))%10;
       			}
       		cout<<i<<"*a="<<a<<"flag="<<flag<<endl;
       	}
       return flag;
    }
int main()
{
	long long a;
	cin>>a;
	cout<<trailingZeros(a);
	return 0;
}
答案虽然没问题 但是思来想去 还是做了许多冗余操作:
    既然阶乘数只与5有关  为何我不直接越过数本身 判断n包含5的个数呢。
最终代码:
    
class Solution {
public:
    /*
     * @param n: A long integer
     * @return: An integer, denote the number of trailing zeros in n!
     */
    long long trailingZeros(long long n) {
        	// write your code here
        long long count = 0;
        long long temp=n/5;
        while (temp!=0) {
            count+=temp;
            temp/=5;
        }
        return count;
    }
};
成了~!