HDU 4180 扩展欧几里得

RealPhobia

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 376    Accepted Submission(s): 151

Problem Description

Bert
is a programmer with a real fear of floating point arithmetic. Bert has
quite successfully used rational numbers to write his programs but he
does not like it when the denominator grows large. Your task is to help
Bert by writing a program that decreases the denominator of a rational
number, whilst introducing the smallest error possible. For a rational
number A/B, where B > 2 and 0 < A < B, your program needs to
identify a rational number C/D such that:
1. 0 < C < D < B, and
2. the error |A/B - C/D| is the minimum over all possible values of C and D, and
3. D is the smallest such positive integer.

Input

The
input starts with an integer K (1 <= K <= 1000) that represents
the number of cases on a line by itself. Each of the following K lines
describes one of the cases and consists of a fraction formatted as two
integers, A and B, separated by “/” such that:
1. B is a 32 bit integer strictly greater than 2, and
2. 0 < A < B

Output

For
each case, the output consists of a fraction on a line by itself. The
fraction should be formatted as two integers separated by “/”.

Sample Input

3
1/4
2/3
13/21

Sample Output

1/3
1/2
8/13

Source

The 2011 South Pacific Programming Contest

Recommend

lcy   |   We have carefully selected several similar problems for you:  4186 4181 4182 4183 4179

#include<stdio.h>
#include<string.h>

long long gcd1(long long a,long long b,long long &x,long long &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    long long d = gcd1(b,a%b,x,y);
    long long t = x;
    x = y;
    y = t - a/b*y;
    return d;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long a,b;
        scanf("%lld/%lld",&a,&b);
        long long x = 0,y = 0;
        long long p = gcd1(a,b,x,y);
        //printf("%lld,%lld\n",x,y);
        //printf("---%lld\n",p);
        //printf("==%lld %lld\n",a,b);
        if(p != 1)
        {
            printf("%lld/%lld\n",a/p,b/p);
            continue;
        }
        if(a == 1)
        {
            printf("1/%lld\n",b-1);
            continue;
        }
        long long x1 = 0,y1 = 0;
        if(x > 0)
        {
            x1 = (a + y)%a;
            y1 = (b - x)%b;
        }
        else
        {
            x1 = (a - y)%a;
            y1 = (b + x)%b;
        }
        //printf("%lld %lld %lld %lld\n",x1,y1);
        printf("%lld/%lld\n",x1,y1);
    }
    return 0;
}
时间: 2024-10-11 20:58:55

HDU 4180 扩展欧几里得的相关文章

hdu 1576 扩展欧几里得

(A/B)%9973=K A/B=K+9973*X A=BK+9973*X*B A%9973=n; BK%9973=n; BK=n+9973*Y (K/n)*B+(-Y/n)*9973=GCD(B,9973)=1; 求出k/n,求出k 1 /* 2 扩展欧几里得 3 扩展欧几里德算法是用来在已知a, b求解一组x,y使得ax+by = Gcd(a, b) =d(解一定存在,根据数论中的相关定理) 4 */ 5 #include<cstdio> 6 #include<iostream>

hdu 2669(扩展欧几里得)

Romantic Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4400    Accepted Submission(s): 1852 Problem Description The Sky is Sprite.The Birds is Fly in the Sky.The Wind is Wonderful.Blew Throw t

HDU RSA 扩展欧几里得

Problem Description RSA is one of the most powerful methods to encrypt data. The RSA algorithm is described as follow: > choose two large prime integer p, q> calculate n = p × q, calculate F(n) = (p - 1) × (q - 1)> choose an integer e(1 < e &l

HDU 2669 (扩展欧几里得入门)

练习一下数学知识了.. [题目链接]click here~~ [题目大意]Find the nonnegative integer X and integer Y to satisfy X*a + Y*b = 1. If no such answer print "sorry" instead. 求满足式子的x和y否则输出"sorry" [解题思路]扩展欧几里得的基础了, 扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足 等式: ax+by = gcd

[ACM] hdu 3923 Invoker (Poyla计数,快速幂运算,扩展欧几里得或费马小定理)

Invoker Problem Description On of Vance's favourite hero is Invoker, Kael. As many people knows Kael can control the elements and combine them to invoke a powerful skill. Vance like Kael very much so he changes the map to make Kael more powerful. In

hdu 5512 Pagodas 扩展欧几里得推导+GCD

题目链接 题意:开始有a,b两点,之后可以按照a-b,a+b的方法生成[1,n]中没有的点,Yuwgna 为先手, Iaka后手.最后不能再生成点的一方输: (1 <= n <= 20000) T组数据T <= 500; 思路:由扩展欧几里得知道对于任意正整数,一定存在整数x,y使得 x*a + y*b = gcd(a,b);并且这个gcd是a,b组成的最小正整数:同时也知道了这也是两个点之间的最小距离: 之后直接求点的个数即可: ps:这道题我竟然想到了组合游戏..明显没有说双方都要用

扩展欧几里得 HDU 1576

题意;要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1). 因为:A%9973=n; 所以:9973*y+n=A: 设:A/B=x;(可以整除) 所以:9973*y+n=B*x; 所以:B*x-9973*y=n; ①式 又因为:gcd(B,9973) = 1; 所以必存在 x1*B+9973*y1=1;②式 ②式*n=①式 所以只要求出x1,就可以得到x,又因为x=a/b,只要在 mod 9973就是答案了. 现

[ACM] hdu 3923 Invoker (Poyla计数,高速幂运算,扩展欧几里得或费马小定理)

Invoker Problem Description On of Vance's favourite hero is Invoker, Kael. As many people knows Kael can control the elements and combine them to invoke a powerful skill. Vance like Kael very much so he changes the map to make Kael more powerful. In

HDU 4596 - Yet another end of the world(扩展欧几里得)

题意:给定一系列的虫洞,每个虫洞都有自己的x,y,z,当你的 id 对 x 取余后结果落在[ y,z ]区间内,则会被吸引,被两个或两个以上的虫洞吸引会有危险,求能否宇宙飞船能否起飞. 枚举每两个虫洞,有 id - k1 * x1 = u id - k2 * x2 = v 其中k1与k2分别为 id / x1 与 id / x2,u与v分别为求余后的结果. 两式相减得  k2 * x2 - k1 * x1 = u - v 根据扩展欧几里得,判断 u - v 的取值是否能取到 gcd(x1, x2