題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6624
題目大意:給定,存在兩整數,求解滿足的最小值。
思路:
令,則存在不等式,
變換一下得到:,我們要解出這個不等式中的值。
這時候可以想到運用類似於輾轉相除法的形式來解決這個問題:
(1)令,
(2)如果,則令(因爲不含等號,所以要加1)跳出循環。否則就執行(3)。
(3)不等式同步減掉,不等式變爲:,分子分母翻轉一下得到:,這個式子和最初得到的原式是不是有點相像,兩式對應一下遞歸就了。
證明:算法正確性菜雞無法證明,很像輾轉相除法。
AC代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll p,xx;
ll b,c;
void solve(ll p,ll x,ll &b,ll &c,ll pp,ll y)//y=x-1
{
ll z1=p/x;
ll z2=pp/y;
if(z1!=z2){
c=1;
b=z1+1;//因爲不等式不帶等號
return ;
}
p-=z1*x;
pp-=z1*y;
b-=c*z1;
solve(y,pp,c,b,x,p);
b+=c*z1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%lld%lld",&p,&xx);
b=0;
c=0;
solve(p,xx,b,c,p,xx-1);//按照不等式從左到右依次傳參
ll a=b*xx-c*p;
printf("%lld/%lld\n",a,b);
}
return 0;
}
/*
3
11 7
998244353 554580197
998244353 998244352
2/5
8/9
499122176/499122177
*/