• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
mengxm
博客园    首页    新随笔    联系   管理    订阅  订阅

poj1061

卧槽。。。。困了我一年的扩展欧几里得终于做出了,好吧我承认我特别水,关于扩展欧几里得可以看我的博客有介绍

这里主要讲一下具体求解过程,a*x+b*y=c, r=gcd(a,b), 如果c可以整除r则x,y有整数解否则没有,然后整个式子除以r

得a`*x+b`*y=c`, 此时gcd(a`,b`)=1,然后通过扩展欧几里得求出a`*x+b`*y=gcd(a`,b`)=1的一组解(x`,y`),整个式子乘以c`

得a`*(x`*c`)+b`*(y`*c`)=c`,有x=x`*c`+t*b`,y=y`*c`-t*a`,(t位整数),

此题要求解最小非负的x,可以利用%运算(a%b)的到最靠近0的数字(符号取决于a),然后判断正负加一次b的绝对值。

#include <stdio.h>
#define abs(a) ((a)<0?-(a):(a))
__int64 gcd(__int64 a,__int64 b)
{
    return !b?a:gcd(b,a%b);
}
void exgcd(__int64 i,__int64 j,__int64 &a,__int64 &b)
{
    if(!j) a=1,b=0;
    else exgcd(j,i%j,b,a),b-=(a*(i/j));
}
int main()
{
    __int64 x,y,n,m,l;
    while(scanf("%I64d %I64d %I64d %I64d %I64d",&x,&y,&m,&n,&l)==5)
    {
        x=(x+l)%l;
        y=(y+l)%l;
        __int64 i,j,k,r,a,b;
        i=n-m,j=l,k=x-y;
        r=gcd(i,j);
        if(k%r)
            printf("Impossible\n");
        else
        {
            k/=r,i/=r,j/=r;
            exgcd(i,j,a,b);
            a=(k*a)%j;
            if(a<0) a+=abs(j);
            printf("%I64d\n",a);
        }
    }
    return 0;
}

  

posted @ 2012-02-08 20:32  mengxm  阅读(996)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3