zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    【转】SQL SERVER函数无法执行对数据库的修改语句
    【转】用SQL实现树的查询
    HTML: < 和 > 是何方神圣
    ASP.NET的一些小问题
    C#的MD5哈希值计算
    高度自适应的CSS
    [转]WCF类型共享技巧
    使用.net的跟踪诊断来记录wcf消息
    【转】js frame 框架编程
    js点击button按钮跳转到页面代码
  • 原文地址:https://www.cnblogs.com/wt20/p/5768841.html
Copyright © 2011-2022 走看看