蒟蒻求助

P1591 阶乘数码

dtrthg @ 2021-07-25 21:52:44

嘤嘤嘤

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a[1010][5010],len[1010],cnt;
/*
数组用于存储1~1000的阶乘,数组len用于存储每个阶乘的长度,累加器cnt用于存储数码出现次数
数组a第二维为阶乘的位数,例如数组第1位开始,并反着存储,则a[5][1]为0,a[5][2]为2,a[5][3]为1 (5的阶乘为120) 
*/
int main()
{
    a[1][1]=1;
    len[1]=1;
    //本人习惯从1开始,大佬勿喷 
    for(int i=2;i<=1000;i++)
    {
        int ws=len[i-1];//先假设i的阶乘长度与上一位相同 

        for(int j=1;j<=ws;j++)
        {
            a[i][j]+=a[i-1][j]*i;
/*
将上一位的第j位乘i,例如i=5,则ws=2,循环2次。第一次a[i][1]加上4*5,(4的阶乘为24,反过来为42),第二次a[i][2]加上2*5 
*/ 

            if(a[i][j]>9)
            {
                a[i][j+1]=a[i][j+1]+a[i][j]/10;
                a[i][j]%=10;
            }

            //处理进位 
        }

        ws+=10;//因为乘法可能会进好几位 
        while(a[i][ws-1]==0)
        //如果ws-1位是0,则ws--。把ws减1是因为实际位数会比ws少一位 
        {
            ws--;
        }
        len[i]=ws;
        //位数 (长度) 处理 
    }
//预处理 
    int t;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        int n,x;
        cin>>n>>x;

        for(int j=1;j<=len[n];j++)
        {
            if(a[n][j]==x) cnt++;
        }
        //遍历 
        cout<<cnt<<endl;
    }
    return 0;
}

救救孩子吧QVQ


by 阿巴人上人 @ 2021-07-25 22:18:02

@dtrthg 估计是高精,我去试试


by dtrthg @ 2021-07-25 22:22:29

@阿巴人上人 谢谢大佬帮助


by MC小萌新 @ 2021-07-25 22:25:32

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a[1010][5010],len[1010],cnt;
/*
数组用于存储1~1000的阶乘,数组len用于存储每个阶乘的长度,累加器cnt用于存储数码出现次数
数组a第二维为阶乘的位数,例如数组第1位开始,并反着存储,则a[5][1]为0,a[5][2]为2,a[5][3]为1 (5的阶乘为120) 
*/
int main()
{
    a[1][1]=1;
    len[1]=1;
    //本人习惯从1开始,大佬勿喷 
    for(int i=2;i<=1000;i++)
    {
        int ws=len[i-1];//先假设i的阶乘长度与上一位相同 
        for(int j=1;j<=ws;j++)
                a[i][j]=a[i-1][j]*i;
/*
将上一位的第j位乘i,例如i=5,则ws=2,循环2次。第一次a[i][1]加上4*5,(4的阶乘为24,反过来为42),第二次a[i][2]加上2*5 
*/ 
            //处理进位 
        for(int j=1;j<=ws;++j){
            if(a[i][j]>=10){
                a[i][j+1]+=a[i][j]/10;
                if(j==ws)
                    ws++;
                a[i][j]%=10;
            }
        }
        len[i]=ws;
     //   for(int j=len[i];j>=1;--j)
     //       cout<<a[i][j];
      //  cout<<endl;

        /*
        ws+=10;//因为乘法可能会进好几位 
        while(a[i][ws-1]==0)
        //如果ws-1位是0,则ws--。把ws减1是因为实际位数会比ws少一位 
        {
            ws--;
        }
        len[i]=ws;*/
        //位数 (长度) 处理 
    }
//预处理 
    int t;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        cnt=0;
        int n,x;
        cin>>n>>x;
        for(int j=1;j<=len[n];j++){
            if(a[n][j]==x) cnt++;
        }
        //遍历 
        cout<<cnt<<endl;
    }
    return 0;
}

by MC小萌新 @ 2021-07-25 22:27:27

主要有一个大错误:乘的时候把进位一起乘了


by MC小萌新 @ 2021-07-25 22:28:25

还有就是最后询问的时候每次 cnt 没有归 0


by dtrthg @ 2021-07-25 22:34:58

@MC小萌新 过了,谢谢巨佬帮助


by 阿巴人上人 @ 2021-07-25 22:45:25

@dtrthg 我猜的没错,就是一道高精处理,上代码

#include<bits/stdc++.h>
using namespace std;
int t,n,a;
int s[5001];
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        for(int i=2; i<=n; i++)
            s[i]=0;
        s[1]=1;
        long long sum=0;
        int ws=1;
        scanf("%d%d",&n,&a);
        for(int i=2; i<=n; i++)
        {
            int jw=0;
            for(int j=1; j<=ws; j++)
            {
                s[j]=s[j]*i+jw;
                jw=s[j]/10;
                s[j]%=10;
            }
            while(jw>0)
            {
                ws++;
                s[ws]=jw%10;
                jw/=10;
            }
        }
        //for(int i=1; i<=ws; i++)cout<<s[i]<<" ";
        //cout<<endl;
        for(int i=1; i<=ws; i++)if(s[i]==a)sum++;
        cout<<sum<<endl;
    }
    return 0;
}

by dtrthg @ 2021-07-25 22:52:01

@阿巴人上人 谢谢


|