码迷,mamicode.com
首页 > 编程语言 > 详细

HDU 1576 A/B (扩展欧几里德算法)

时间:2015-04-26 09:20:14      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

连接:http://acm.hdu.edu.cn/showproblem.php?pid=1576

Sample Input
2 1000 53 87 123456789
 

Sample Output
7922 6060

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

数论的解法:数学式子推一推,大循环就出来了,没想到啊。

设A = k * 9973 + n  ,A/ B = C, C = P * 9973 + x,x即为我们所求的答案。易知,A = k* 9973 + n =B * P * 9973 + B * x,化简后得k * 9973 = B * P * 9973 + B * x - n,因此(B * x - n)%9973 = 0,n的值知道,B的值知道,又因为x的取值范围是0到9972,因此枚举x的值即可,满足条件的就是答案。

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int main()
{
    int N;
    scanf("%d",&N);
    while(N--)
    {
        long long  n,b;
        long long x;
        scanf("%lld%lld",&n,&b);
        for(int i=0;i<9973;++i)
        {

            if((b*i-n)%9973 == 0)
            {
                x=i;
                break;
            }

        }
        printf("%lld\n",x);
       
    }
    return 0;
}

扩展欧几里得算法(模板):

__int64 Extended_Euclid(__int64 a,__int64 b,__int64& x,__int64& Y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    __int64 r=Extended_Euclid(b,a%b,x,y)
    __int64 temp=x;x=y;y=t-a/b*y;
    return r; //r为a,b的最大公约数
}

扩展欧几里德算法:
  扩展欧几里德算法是用来在已知的非负整数(否则需要将式子变形,如求5x-13y=1的解则变形为5x+(-13y)=1,然后再对结果做处理即可a, b求解一组x,y使得ax+by = Gcd(a, b) =d(解一定存在,根据数论中的相关定理)扩展欧几里德常用在求解模线性方程及方程组中。

下面是一个使用C++的实现:
  int exGcd(int a, int b, int &x, int &y)
  {
  if(b == 0)
  {
  x = 1;
  y = 0;
  return a; ---很难找出一个这么实现的价值,因为扩展欧几里得还有更大的用途;个人认为定义全局数组更好,不用return r。
  }
  int r = exGcd(b, a % b, x, y);
  int t = x;
  x = y;
  y = t - a / b * y;
  return r;
  }
使用扩展欧几里德算法解决不定方程的办法:
  对于不定整数方程pa+qb=c,若 c mod Gcd(a, b)=0,则该方程存在整数解,否则不存在整数解。
  上面已经列出找一个整数解的方法,在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,可以证明p0为0附近的最小解,*p * a+q * b = Gcd(a, b)的其他整数解满足:
  p = p0 + b/Gcd(a, b) * t
  q = q0 - a/Gcd(a, b) * t(其中t为任意整数,p,q中的t相同)
  至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(a, b)的每个解乘上 c/Gcd(a, b) 即可
  在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,应该是
  得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),p * a+q * b = c的其他整数解满足:
  p = p1 + b/Gcd(a, b) * t
  q = q1 - a/Gcd(a, b) * t(其中t为任意整数,p,q中的t相同)
  p 、q就是p * a+q * b = c的所有整数解。

// Note:Your choice is C++ IDE
#include <iostream>
using namespace std;
#define k 9973
int uex(int a,int b,int &x,int &y)
{
    int r;
    int t;
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    r=uex(b,a%b,x,y);
    t=x;
    x=y;
    y=t-a/b*y;
    return r;
}
int main()
{
    int T,t,n,b,x,y;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&b);
        uex(b,k,x,y);
        x*=n;
        if(x<0)
        {
            t=-x;
            t=t%k;
            x=k-t;     //或者不用t变量  直接x=k-(-x)%k;或者用while(x<0){x+=k/1;},不过不推荐使用,因为可能会超时!最好用 x=(x%k+k)%k即可,if语句也不用了;  
        }
        printf("%d\n",x%k);
    }
    return 0;
}
还没看懂

HDU 1576 A/B (扩展欧几里德算法)

标签:

原文地址:http://blog.csdn.net/a197p/article/details/45276749

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!