我的专业是信息对抗所以我们就学习了一些信安数学基础,我也是蛮喜欢的,所以就写写求解一次同余式的代码
一次同余式的定义:
一次同余方程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;
}