Description
计算
(0! + 1! + 2! + 3! + 4! + … + n!)%m
Input
第一行输入t,表示测试数据组数
每组数据输入两个数n和m
0 < T <= 20
0 <= n < 10^100 (没有前导零)
0 < m < 1000000
Output
输出(0! + 1! + 2! + 3! + 4! + … + n!)%m的答案
Sample Input
Raw
1
10 861017
Sample Output
Raw
593846
解题思路:这个n非常大,直接暴力肯定会超时,但是m的值却不大,求的阶乘每次都会模上m,大于m的数的阶乘就不用计算了,因为大于m的数的阶乘模上m就等于0了,所有这个题最大到1000000。
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
int main()
{
int t;
char n[105],m[105];//n的位数较大,用数组存放
scanf("%d",&t);
while(t--){
scanf("%s%s",&n,&m);
int lenn=strlen(n);
int lenm=strlen(m);
int mod=0;
int x=0;
for(int i=0;i<=lenm-1;i++){
int t=m[i]-'0';
mod=mod*10+t;
}
if(lenn>lenm){
x=mod;
}
else if(lenn<lenm){
for(int i=0;i<=lenn-1;i++){
int t=n[i]-'0';
x=x*10+t;
}
}
else if(lenn==lenm){
if(strcmp(n,m)<0){
for(int i=0;i<=lenn-1;i++){
int t=n[i]-'0';
x=x*10+t;
}
}
else
x=mod;
}//找到n和m中小的那一个数
long long jc=1;
long long sum=1;
for(int i=1;i<=x;i++){
jc*=i;
jc%=mod;
sum+=jc;
sum%=mod;
}
printf("%lld\n",sum);
}
return 0;
}