模运算(附加几种数据类型的数据范围判断)-hdu3123

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3123

预备知识点:

(a+b)%m=[(a%m)+(b%m)]%m
(a*b)%m=[(a%m)*(b%m)]%m
所以(0!+1!+2!+.....+n!)%m=[(0!%m+1!%m)%m+(1!%m)*(2%m)%m}%m.........到K>=n时,K!%m=0

因为此题涉及大数据,因此去了解了一下C/C++语言中计算int,float,double,char四种数据类型所能表示的数据范围:

详见博客:https://blog.csdn.net/wordwarwordwar/article/details/52558687

题目描述:

此题关键点在n的数据范围为0~10^100,所以我用了两种方法来处理此大数据:

1、利用char数组来存大数n,实现大数相加

#include<stdio.h>
#include<iostream>
#include<cstring>
using namespace std;
char a[102];
int main()
{
    int t;
    long long m,ans;
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        scanf("%s",a);
        scanf("%lld",&m);
        long long sum=0;
        int len=strlen(a);
        for(int i=0;i<len;i++)
        {
            sum=sum*10+(a[i]-'0');
            if(sum>m)
                break;
        }
        if(sum>=m)
        {
            ans=m-1;
            for(int i=ans-1;i>=1;i--)
            {
                ans=(((ans+1)%m)*i%m)%m;
            }
        }
        else
        {
            ans=sum;
            for(int i=ans-1;i>=1;i--)
                ans=(((ans+1)%m)*i%m)%m;
        }
        printf("%lld\n",(ans+1)%m);
    }
    return 0;
}

2、因为double型能表示的数据范围在1.7 x 10^(-308)~ 1.7 x 10^(+308)之间,而n的范围为0~10^100,所以可以利用double型来存大数n。

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 int main()
 6 {
 7     int t;
 8     double a;
 9     long long m,ans;
10     scanf("%d",&t);
11     while(t--)
12     {
13         ans=0;
14         scanf("%lf%lld",&a,&m);
15         if(a>=m)
16         {
17             ans=m-1;
18             for(int i=ans-1;i>=1;i--)
19             {
20                 ans=(((ans+1)%m)*i%m)%m;
21             }
22         }
23         else
24         {
25             ans=a;
26             for(int i=ans-1;i>=1;i--)
27                 ans=(((ans+1)%m)*i%m)%m;
28         }
29         printf("%lld\n",(ans+1)%m);
30     }
31     return 0;
32 }

猜你喜欢

转载自www.cnblogs.com/LJHAHA/p/10004093.html