HDU1576 A/B【扩展欧几里得算法】


问题链接HDU1576 A/B

问题简述:参见上述链接。

问题分析这个问题可以用解整数的不定方程来解决,即使用扩展欧几里德算法。

根据题意,输入的n=A%9973(没有输入A),A%B=0(A必能被B整除),B与9973互素(GCD(B,9973)=1)。

解题过程首先是建立方程,然后才能编写程序。

设x=(A/B)%9973(x是最终想计算的值),则9973k+x=A/B(k为整数),得A=9973Bk+xB。

因为n=A%9973与A=9973Bk+xB,所以xB%9973=n,得xB=n+9973y。

故:(x/n)B+(-y/n)9973=1=GCD(B,9973),该方程有解。

要求x和y,先求X=x/n和Y=-y/n,即先解方程BX+9973Y=1。

最后,x=X*n。

需要注意的是,求得的x有可能是负值,需要进行调整。

不过,这个计算方法好像比较花时间。

程序说明:(略)。


AC的C语言程序如下:

#include <stdio.h>

// 递推法实现扩展欧几里德算法
long exgcd(long a, long b, long *x, long *y)
{
    long x0=1, y0=0, x1=0, y1=1;
    long r, q;
    *x=0;
    *y=1;

    r = a % b;
    q = (a - r) / b;
    while(r)
    {
        *x = x0 - q * x1;
        *y = y0 - q * y1;
        x0 = x1;
        y0 = y1;
        x1 = *x;
        y1 = *y;

        a = b;
        b = r;
        r = a % b;
        q = (a - r) / b;
    }
    return b;
}

int main(void)
{
    int t, i;
    long n, b, a=9973, x, y;

    scanf("%d", &t);
    for(i=0; i<t; i++) {
        scanf("%ld%ld", &n, &b);
        exgcd(b, a, &x, &y);
        x = (x + a) % a;        // x有可能为负,需要调整
        printf("%ld\n", x*n%a);
    }

    return 0;
}


优质内容筛选与推荐>>
1、ExtJs自学教程(1):一切从API開始
2、javascript-DOM(3)
3、EasyDarwin相关Android安卓客户端EasyPusher/EasyPlayer/EasyCamera/EasyClient在无开发环境进行log抓取
4、转贴: 为什么要使用firefox火狐浏览器的17个理由(附加两条)
5、HTML语义化标签点滴


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号