http://acm.hdu.edu.cn/showproblem.php?pid=4180
题意为给定一个数(a/b),求另一个(c/d) ,要求d < b , 并且要求fabs( a / b - c / d ) 要最小 ;
当 a 与 b 互质的时候 ,有a * d + 1 == b * c || a * d == b * c + 1 ; 然后通过exgcd 求出c 和 d 然后比较d的大小,最后输出结果;
需要注意的是,这只是其中的一种情况, 当a 和 b 存在最大公约数时,直接整除即可,当a为1 的时候,因为分子已经处于最小的状态,因此只需要改变分母的大小即可,有因为d < b 并且要求最小,所以b - 1;
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std ;
#define INT __int64
INT x , y ;
INT exgcd( INT a , INT b ,INT &x , INT &y )
{
if( b == 0 )
{
x = 1 ;
y = 0 ;
return a ;
}
INT r = exgcd( b , a % b , x , y ) ;
INT t = x ;
x = y ;
y = t - a / b * y ;
return r ;
}
int main()
{
int Case ;
INT m , n ;
cin >> Case ;
while( Case-- )
{
scanf( "%I64d/%I64d" ,&m , &n );
INT d = exgcd( m , n , x , y) ;
if( d != 1 )
{
cout << m / d << "/" << n/d << endl ;
continue ;
}
if( m == 1 )
{
cout << "1/" << n - 1 << endl ;
continue ;
}
INT x1 = ( x + n ) % n ;
INT y1 = ( -y + m ) % m;
INT x2 = ( -x + n ) % n ;
INT y2 = ( y + m ) % m ;
if( x1 > x2 )
printf( "%I64d/%I64d\n" , y1 , x1 ) ;
else
printf( "%I64d/%I64d\n" , y2 , x2 ) ;
}
return 0 ;
}