题目大意
求整数p和q使得 a/b<q/p<c/d 且p最小
类欧
一个显然的结论最小化分子或分母都是对的。
首先如果a>=b,显然可以先减去几个整数变成真分数。
那么如果
a<b
呢?
ab<qp<cd
dc<pq<ba
递归下去计算。
边界是a=0的时候。
容易看出变成真分数的过程是a%b,翻过来是两个调换。
这是经典的类欧几里得算法。详见代码
#include<cstdio>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
ll i,j,k,l,t,n,m,a,b,c,d,p,q,ca;
void likegcd(int a,int b,int c,int d){
if (a==0){
q=1;p=floor(d/c)+1;
return;
}
if (a>=b){
likegcd(a%b,b,c-d*(a/b),d);
q+=(ll)p*(a/b);
return;
}
if (c>d){
p=q=1;
return;
}
likegcd(d,c,b,a);
swap(p,q);
}
int main(){
scanf("%d",&ca);
while (ca--){
scanf("%d%d%d%d",&a,&b,&c,&d);
likegcd(a,b,c,d);
printf("%lld/%lld\n",q,p);
}
}