P1134 阶乘问题

题目链接

点这里

思路

这题太对不起它普及/提高-的标签了,这nm也太水了吧

思路一

直接暴力乘

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<cstring>
using namespace std;
const int maxn=999999999;
const int minn=-999999999;
inline int read() {
	char c = getchar(); int x = 0, f = 1;
	while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x * f;
}
int main()
{
    long long int n,ans=1;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        ans*=i;
        while(ans%10==0) ans/=10;
        ans%=1000000;
    }
    cout<<ans%10;
    return 0;
}

思路二

分析10怎么出现.发现如果两个数的因数中分别有2,5.那么相乘末尾一定有0.于是统计1~N中每个数的因数中2和5的个数.用2的个数减去5的个数(2的个数一定比5的个数多).剩下的是会对答案(即末尾的数)造成影响.之后大胆mod 10 就行了.

代码懒得打了

思路三

我也没想到这种思路,就借鉴了大佬们的做法,咕咕咕果然我太菜了

太巨了,ora%%%%

#include <bits/stdc++.h>

using namespace std;

int a, x, t, z, y;

vector<int> a5;

void ito5() {while (a) a5.push_back(a % 5), a /= 5;}

int main(int argc, char const* argv[])
{
    scanf("%d", &a), ito5();
    for (int i = 0; i < a5.size(); i += 1)
    {
        if (!(a5[i] & 1)) t += a5[i];
        x += a5[i] * i;
    }
    z = (x + (t >> 1)) % 4, y = (1 << z);
    printf("%d\n", (6 * (y & 1) + y * (1 - (y & 1))) % 10);
    return 0;
}
posted @ 2019-05-17 17:29  pyyyyyy  阅读(144)  评论(1编辑  收藏  举报