反向因子Inverse Factorial

题目描述

A factorial n! of a positive integer n is defined as the product of all positive integers smaller than or equal to n. For example,
21!=1⋅2⋅3⋅…⋅21=51090942171709440000.

It is straightforward to calculate the factorial of a small integer, and you have probably done it many times before. In this problem, however, your task is reversed. You are given the value of n!and you have to find the value of n.

输入

The input contains the factorial n! of a positive integer n. The number of digits of n! is at most 106.

输出

Output the value of n.

样例输入

120

样例输出

5

大意就是给一个n的阶乘,让你求n;
这个题着实有点坑,思路就是每个数的零的个数和后几位非零的数是唯一的,所以就定义两个数组分别装零的个数和非零的后几位,首先字符串长度1e6的话数组1e5就够了,然后关键是要确定后几位才能使每个数都不同,这里我取了后八位,切记不能每次求余后八位,要取到后九位这样才会保证每次的后八位都是正确的(血的教训啊!)
然后再分析字符串即可。

#include <bits/stdc++.h>

using namespace std;

long long int b[111000];//每次求余九位的数组;

int a[111000];//记录每个数零的个数;

int c[111000];//每个数的去掉后缀零的后八位,通过b数组获得,不能直接用b数组,因为求余出来的第九位不一定对;

int main()

{

    int n=0;
    long long int tt=1;
    for(int i=1; i<=110000; i++)
    {
        int k=0;
        tt=tt*i;
        for(int w=0;; w++)
        {
            if(tt%10==0)
            {
                tt=tt/10;
            }
            else
            {
                tt=tt%1000000000;//存入b数组
                c[i]=tt%100000000;//真正用来判断的c数组
                break;
            }
        }
        int oo=i;
        for(int j=0;; j++)
        {
            if(oo%5==0)//i能被5除几次就加几个零;
            {
            oo=oo/5;
                k++;
            }
            else
            {
                break;
            }
        }
        n+=k;
        a[i]=n;
        b[i]=tt;

    }
    char ans[1100000];
    scanf("%s",&ans);
    int p=strlen(ans);
    int pp=0;//记录字符串后缀零的个数
    int wer;//记录除去后缀零的后八位
    for(int i=p-1; i>=0; i--)
    {
        if(ans[i]=='0')
        {
            pp++;

        }
        else
        {
            wer=ans[i]-'0';
            int poq=10;
            int maxx=max(0,i-7);//防止越界
            for(int ww=i-1;ww>=maxx;ww--)
            {
                wer+=(ans[ww]-'0')*poq;
                poq*=10;
            }

            break;
        }
    }
    for(int i=1; i<110000; i++)
    {
        if(a[i]==pp&&c[i]==wer)
        {
            printf("%d\n",i);
            break;
        }
    }
    return 0;
}
//40!=815915283247897734345611269596115894272000000000

//41!=33452526613163807108170062053440751665152000000000

//42!=1405006117752879898543142606244511569936384000000000

//43!=60415263063373835637355132068513997507264512000000000

//44!=2658271574788448768043625811014615890319638528000000000

//45!=119622220865480194561963161495657715064383733760000000000

//49!=608281864034267560872252163321295376887552831379210240000000000

//50!=30414093201713378043612608166064768844377641568960512000000000000

  

猜你喜欢

转载自www.cnblogs.com/xiaolaji/p/9124970.html
今日推荐