Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 938 Accepted Submission(s): 435
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.
1. B is a 32 bit integer strictly greater than 2, and
2. 0 < A < B
| A/B - C/D |= minn <=> | AD - BC| / BD =minn
如果AB可以约分的话直接约分就是答案。否则说明 gcd(A,B)=1, 我们有 A*D+B*C = gcd(A,B) = 1,原分子加了绝对值,有两种情况
D>0,C<0 或者是 D<0,C>0 ,解完之后对D分正负讨论一下那个使得分母更大就选那个,分子已经是1了。
因为D<B,所以记得%B,正负分别对应唯一的一个解。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 #define LL long long 5 #define mp make_pair 6 #define pb push_back 7 #define inf 0x3f3f3f3f 8 void exgcd(LL a,LL b,LL &d,LL &x,LL &y){ 9 if(!b){d=a;x=1;y=0;} 10 else{exgcd(b,a%b,d,y,x);y-=x*(a/b);} 11 } 12 int main(){ 13 LL a,b,d,x,y; 14 int t; 15 cin>>t; 16 while(t--){ 17 scanf("%lld/%lld",&a,&b); 18 exgcd(a,b,d,x,y); 19 if(d!=1){ 20 printf("%lld/%lld\n",a/d,b/d); 21 } 22 else{ 23 LL d1,d2,c1,c2; 24 d1=(x%b+b)%b,c1=-(1-a*d1)/b; 25 d2=-(x%b-b)%b,c2=(1+a*d2)/b; 26 if(d1>d2){ 27 printf("%lld/%lld\n",c1,d1); 28 } 29 else{ 30 printf("%lld/%lld\n",c2,d2); 31 } 32 } 33 } 34 return 0; 35 }