• poj2891


    /*
    
        题目大意:对于m%a1=r1,m%a2=r2...m%ak=rk,求最小的非负的m的值
    
        联立前面两个方程组则有a1*x-a2*y=r2-r1;
        可利用欧几里得算法求出最小的非负x  那么满足前两个方程的一个特解m=a1*x+r1;
        所有解M=m+x*LCD(a1,a2);---LCD(a1,a2)最小公倍数
        在联立第3个方程,另a1 = LCD(a1,a2),a2 = a3,r2=r3;
        那么有方程 a1*x-a2*y=r2-m,继续利用欧几里得算出x,得到新的m即可
    */
    
    
    #include <iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    __int64 m,t,n,a1,r1,a2,r2,ans,d;
    bool flag;
    __int64 extend_euclid(__int64 a,__int64 b,__int64 &x,__int64 &y)
    {
          //b等于0时递归结束,得到该步的解,通过该解返回到上一步的出上一步的解
        if(b==0)
         {
             x=1;
             y=0;
             return a;
         }
         __int64 d = extend_euclid(b,a%b,x,y);
         __int64 t = x;
         x=y;
         y=t-a/b*y;
         return d;//a,b的最大公约数
    }
    void fun(__int64 a,__int64 b,__int64 c)
    {
        d = extend_euclid(a,b,ans,t);//最大公约数
        if(c%d!=0)
            flag=false;
        ans=ans*c/d;
        __int64 r = fabs(b/d);
        ans = (ans%r+r)%r;//得到最小非负整数解
        m=m+ans*a1;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(scanf("%I64d",&n)!=EOF)
        {
            flag = true;
            ans= 0;
            scanf("%I64d%I64d",&a1,&r1);
            m=r1;
            for(int i=1;i<n;i++)
            {
                scanf("%I64d%I64d",&a2,&r2);
                fun(a1,-a2,r2-m);
                a1=fabs(a1*a2/d);//保证最小公倍数为正数
            }
            if(!flag)
                printf("-1
    ");
            else
                printf("%I64d
    ",m);
        }
    
        return 0;
    }
  • 相关阅读:
    关于jQuery的两对小括号()()的说明
    高效能 DBA 的七个习惯
    Div+CSS网站设计的优点
    .Net上传图片按比例自动缩小或放大
    SEO草根技术基础—DIV+CSS
    asp.net连接Mysql(connector/net 5.0)
    大型网站(高访问、海量数据)技术架构
    ISO Latin1字符集
    CuteEditor学习总结技巧
    Craigslist 的数据库架构
  • 原文地址:https://www.cnblogs.com/wt20/p/5768841.html
Copyright © 2020-2023  润新知