扩展欧几里得、中国剩余定理 入门指南

欧几里得算法

求两个数的最大公约数 gcd(a,b)

gcd(a,b)=gcd(b,a%b)


扩展欧几里得

求出A,B的最大公约数,且求出X、Y满足 AX+BY=GCD(A,B)

当B=0时,有X=1、Y=0时等式成立。

当B>0时,在欧几里得基础上。已知GCD(A,B)=GCD(B,A%B)

递归求出X'、Y' 满足 BX'+(A%B)Y'=GCD(B,A%B)=GCD(A,B)

化简得 AY'+B(X'-A/B*Y')=GCD(A,B)

故 X=Y',Y=X'-A/B*Y'


中国剩余定理

求方程组 x≡ai (mod mi) 的解x。

其中 mi 两两互质。

解在模下是唯一的,

其中,而为模的逆元。


POJ 1006 Biorhythms

人自出生起就有体力,情感和智力三个生理周期,分别为23,28和33天。

一个周期内有一天为峰值,在这一天,人在对应的方面(体力,情感或智力)表现最好。

通常这三个周期的峰值不会是同一天。

现在给出三个日期,分别对应于体力,情感,智力出现峰值的日期。

然后再给出一个起始日期,要求从这一天开始,算出最少再过多少天后三个峰值同时出现。


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int extend_gcd(int a,int b,int &x,int &y){
    if (b==0){
        x=1;y=0;
        return a;
    }
    else{
        int r=extend_gcd(b,a%b,y,x);
        y=y-x*(a/b);
        return r;
    }
}

int CRT(int a[],int m[],int n){
    int M=1;
    for (int i=0;i<n;i++) M*=m[i];
    int ret=0;
    for (int i=0;i<n;i++){
        int x,y;
        int tm=M/m[i];
        extend_gcd(tm,m[i],x,y);
        ret=(ret+tm*x*a[i])%M;
    }
    return (ret+M)%M;
}
int a[5],m[5];
int main()
{
    int p,e,i,d;
    m[0]=23;
    m[1]=28;
    m[2]=33;
    int cas=0;
    while (~scanf("%d%d%d%d",&p,&e,&i,&d)){
        if (p==-1||e==-1||i==-1||d==-1) break;
        a[0]=p;
        a[1]=e;
        a[2]=i;
        int ans=CRT(a,m,3);
        ans=(ans-d+21252)%21252;
        if (ans==0) ans=21252;
        printf("Case %d: the next triple peak occurs in %d days.\n",++cas,ans);
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值