求解一次同余式和中国剩余定理的模板

我的专业是信息对抗所以我们就学习了一些信安数学基础,我也是蛮喜欢的,所以就写写求解一次同余式的代码

一次同余式的定义:
一次同余方程ax≡b(mod)m有解的充分必要条件是(a,m)|b,且当其有解时,其解数为(a,m)。

求解一次同余式

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
int x,y,q;
int gcd(int a,int b)
{
    return b ? gcd(b,a%b):a;
}
void ex_Eulid(int a,int  b)
{
    if(b==0)
    {
        x=1;
        y=0;
        q=a;
    }
    else
    {
        ex_Eulid(b,a%b);
        double temp=x;
        x=y;
        y=temp-a/b*y;
    }
}
int main()
{
    int a,b,m;
    while(~scanf("%d%d%d",&a,&b,&m))
    {
        int mod=m;
        int t=gcd(a,m);
        if(b%t==0)
        {
              printf("同余式有%d个解分别为:\n",t);
              a=a/t;b=b/t;m=m/t;
              ex_Eulid(a,m);
              int x1=((x+m)%m*b)%m;
              for(int i=0;i<t;i++)
              {
                  printf("%d ",(x1+i*m)%mod);
              }
        }
        else
        {
          printf("同余式无解\n");
        }
    }
    return 0;
}

中国剩余定理就是多个一次同余式组

第一种:
#include<bits/stdc++.h>
using namespace std;
int x,y,q;
void ex_Eulid(int a,int  b)
{
    if(b==0)
    {
        x=1;
        y=0;
        q=a;
    }
    else
    {
        ex_Eulid(b,a%b);
        double temp=x;
        x=y;
        y=temp-a/b*y;
    }
}
int main()
{
    int a[110],mod[110],m[110],b[110];
    int n,M=1;
    while(~scanf("%d",&n))
    {
        M=1;
        memset(m,0,sizeof(m));
        memset(b,0,sizeof(b));
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d",&a[i],&mod[i]);
            M*=mod[i];
        }
        for(int i=1; i<=n; i++)
        {
            m[i]=M/mod[i];
            ex_Eulid(m[i],mod[i]);
            b[i]=(x+mod[i])%mod[i];
        }
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            sum=sum+a[i]*m[i]*b[i];
        }
        printf("sum=%d",sum%M);
    }
    return 0;
}

另一种:

#include<bits/stdc++.h>
using namespace std;
int Extended_Euclid(int a,int b,int &x,int &y)    //扩展欧几里得算法
{
    int d;
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    d=Extended_Euclid(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

int Chinese_Remainder(int a[],int w[],int len)    //中国剩余定理  a[]存放余数  w[]存放两两互质的数
{
    int i,x,y,m,n,ret,d;
    ret=0;
    n=1;
    for (i=0; i<len; i++)
        n*=w[i];
    for (i=0; i<len; i++)
    {
        m=n/w[i];
        d=Extended_Euclid(w[i],m,x,y);
        ret=(ret+y*m*a[i])%n;
    }
    return (n+ret%n)%n;
}
int main()
{
    int n,i;
    int w[15],b[15];
    while(~scanf("%d",&n)&&n)
    {
        for (i=0; i<n; i++)
        {
            scanf("%d%d",&b[i],&w[i]);
        }
        printf("%d\n",Chinese_Remainder(b,w,n));
    }
    return 0;
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值