HDUoj 1576 A/B 扩展欧几里德

A/B

Problem Description
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。

Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。

Output
对应每组数据输出(A/B)%9973。

Sample Input
2
1000 53
87 123456789

Sample Output
7922
6060

2种方法,暴力和扩展欧几里德

///这种是简单枚举,暴力枚举每一个可能的A的值,因为B能被A整除,直接用B来倒推A,直到((b*i)-a)%9973 == 0为止,i就是A/B的值了。
#include"stdio.h"
#include"iostream"
#include"algorithm"
#include"string.h"
#include"math.h"
#include"stdlib.h"
#include"queue"

using namespace std;

int main(void)
{
    long long T;
    scanf("%lld",&T);
    while(T--)
    {
        long long a,b; ///题目中的n,B
        scanf("%lld%lld",&a,&b);
        for(long long i = 1;i <= 100000;i++) 
        {
            if(((b*i)-a)%9973 == 0)
            {
                printf("%lld\n",i%9973);
                break;
            }
        }

    }
    return 0;
}

我觉得有一个人的写很好,就摘抄了别人的。
这是地址:http://m.blog.csdn.net/blog/u013067957/38139613
解决该题的关键是:

1、了解扩展欧几里德算法,可以运用其解出gcd(a,b)=ax1+by1中的x1、y1的值

2、由题可得以下内容:

n=A%9973,则n=A-A/9973*9973。又A/B=x,则A=Bx。所以Bx-A/9973*9973=n。即Bx-9973y=n。

到这里我们可以发现:只要求出x的值,即可算出x%9973,也就是(A/B)%9973了。顺利解决了!

3、题目关键转到如何求出x了。题目的输入是n和B,利用扩展欧几里德算法可求出gcd(B,9973)=Bx1+9973y1=1的x1。

等式两边同乘以n,得B(nx1)-9973(-ny1)=n。可知nx1就是Bx-9973y=n的解了!!!即x=nx1。

4、对于第三部得到的x可能是负数,由题这显然是不正确的。

可以做这样的转化:(x%9973+9973)%9973

#include"stdio.h"
#include"iostream"
#include"algorithm"
#include"math.h"

using namespace std;

int x,y;
int exgcd(int a,int b)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a; ///这里不写,上面改成void就会re,不知道为什么,对了,这里的a是最大公约数
    }
    exgcd(b,a%b);
    int temp = x;
    x = y;
    y = temp-a/b*y;
}
int main(void)
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,b;
        scanf("%d%d",&n,&b);
        exgcd(b,9973);
        x = (n*x%9973+9973)%9973;///防止为负
        printf("%d\n",x);
    }
}

你可能感兴趣的:(数论,gcd,扩展欧几里德)