zoukankan      html  css  js  c++  java
  • HDU 1356(欧几里得模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1356

    这是欧几里得的模板题。。。

    1.  [扩展眼欧几里德]给定 a b d找到满足ax+by=d 的令|x|+|y|最小 
    2. | 参考线性同余方程 g=gcd(a,b) , ax0+by0=gcd(a,b) 
    3. | 程的一组解: x=x0*d/g; y=y0*d/g;    
    4. | 方程的全部解:x..=x+b/g*t   y..=y-a/g*t 
    5. | |x|+|y|= | x + b/g*t | + | y - a/g*t | (这里有绝对值,所以要想总体会小,那么里面的值要尽量小)    
    6. | 这个关于t的函数的最小值应该在|y - a/g*t|为零附近,即t=y*g/a 
    7. | 在 y*g/a 附近的两整数点里取t,再直接验证这两点即可。 
    #include<stdio.h>
    __int64 x,y;
    __int64 fabs(__int64 a)
    {
        return a>0?a:-a;
    }
    __int64 exgcd(__int64 a,__int64 b)
    {
        __int64 t,ans;
        if(b==0)
        {
                x=1;
                y=0;
                return a;
        }
        ans=exgcd(b,a%b);
        t=x;
        x=y;
        y=t-a/b*y;
        return ans;
    }
    int main()
    {
        __int64 max,xx,yy,a,b,d,temp,i,flag,aa,bb,t;
        while(scanf("%I64d%I64d%I64d",&a,&b,&d),a||b||d)
        {
             flag=0;
             if(a<b)
             {
                 temp=a;
                 a=b;
                 b=temp;
                 flag=1;
             }
             temp=exgcd(a,b);
             x=x*d/temp;
             y=y*d/temp;
             max=9999999;
             t=y*temp/a;
             for(i=t-1;i<=t+1;i++)
             {
                 xx=fabs(x+b/temp*i);
                 yy=fabs(y-a/temp*i);
                 if(xx+yy<max)
                 {
                    max=xx+yy;
                    aa=xx;
                    bb=yy;
                 }
             } 
             if(flag)
             printf("%I64d %I64d
    ",bb,aa);
             else printf("%I64d %I64d
    ",aa,bb); 
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    SDN作业(4)
    SDN作业(3)
    第一次个人编程作业
    SDN作业(2)
    SDN作业(1)
    第一次博客作业
    浅谈闭包
    预编译And作用域链
    定时器
    window事件
  • 原文地址:https://www.cnblogs.com/huzhenbo113/p/3266710.html
Copyright © 2011-2022 走看看