阶乘数码
题目描述
求 n ! n! n! 中某个数码出现的次数。
输入格式
第一行为 t ( t ≤ 10 ) t(t \leq 10) t(t≤10),表示数据组数。接下来 t t t 行,每行一个正整数 n ( n ≤ 1000 ) n(n \leq 1000) n(n≤1000) 和数码 a a a。
输出格式
对于每组数据,输出一个整数,表示 n ! n! n! 中 a a a 出现的次数。
输入输出样例
输入 #1
2
5 2
7 0
输出 #1
1
2
1.题意解析
这是一道很经典的高精度问题。在这里,使用我在高精度算法解析和高精度赛场用模板分装的bigint
结构体完成这道题。
同时,我们还要定义两个成员函数factor
和stat
。分别用来计算阶乘和统计字符,定义分别如下:
bigint factor()//计算阶乘的函数
{
int n=0;
for(int i=max(len,1);i>=1;i--)//将bigint类型转换成int类型
n*=10,n+=a[i];
bigint fac(1);
for(int i=1;i<=n;i++)
fac=fac*bigint(i);//强制转换
return fac;
}
int stat()//统计字符数的函数
{
int cnt=0;
for(int i=1;i<=max(len,1);i++)
if(a[i]==x)
cnt++;
return cnt;
}
2.代码
#include<bits/stdc++.h>
using namespace std;
struct bigint
{
int len,a[5000];//数字位数不超过5000
bigint(int x=0)
{
memset(a,0,sizeof(a));
for(len=1;x;len++)
a[len]=x%10,x/=10;
len--;
}
int &operator[](int i)
{
return a[i];
}
void flatten(int l)
{
len=l;
for(int i=1;i<=len;i++)
a[i+1]+=a[i]/10,a[i]%=10;
while(!a[len])
len--;
}
friend void print(bigint& x)
{
for(int i=max(x.len,1);i>=1;i--)
cout<<x[i];
}
friend bigint operator+(bigint a,bigint b)
{
bigint c;
int _len=max(a.len,b.len);
for(int i=1;i<=_len;i++)
c[i]=a[i]+b[i];
c.flatten(_len+1);
return c;
}
friend bigint operator*(bigint a,bigint b)//高精度乘高精度
{
bigint c;
int lena=a.len,lenb=b.len;
for(int i=1;i<=lena;i++)
for(int j=1;j<=lenb;j++)
c[i+j-1]+=a[i]*b[j];//计算贡献
c.flatten(lena+lenb);//答案不超过两数的位数
return c;
}
bigint factor()//计算阶乘的函数
{
int n=0;
for(int i=max(len,1);i>=1;i--)//将bigint类型转换成int类型
n*=10,n+=a[i];
bigint fac(1);
for(int i=1;i<=n;i++)
fac=fac*bigint(i);//强制转换
return fac;
}
int stat(int x)//统计字符数的函数
{
int cnt=0;
for(int i=1;i<=max(len,1);i++)
if(a[i]==x)
cnt++;
return cnt;
}
};
int main()
{
int t;
cin>>t;
while(t--)//t组数据
{
int x,n;
cin>>n>>x;
bigint a(n);
a=a.factor();//计算阶乘
cout<<a.stat(x)<<endl;//统计字符数
}
return 0;
}
喜欢就订阅此专辑吧!
【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。
欢迎扫码关注蓝胖子编程教育