牛客oi周赛5t3

这是辣鸡出题人出的一道jb题。我们来看题目,用比较通俗的语言讲就是:将分母最大是m的所有真分数排序,得到有序数列x,求在p/q在序列x中左右两边的数是什么,若没有输出“Yuri is master”(没有分号)

我们先来想无解情况,分别有两种,一种是分子是1,分母是m,另一种是分子式n-1,分母是m,对于这两种,特殊判断即可,下面我们来想有解情况:

我们先求出在p/q右边的分数,设这个分数是x/y,可以列出p/q-x/y>0,化简,可得(xq-py)/qy>0,且(xq-py)≥1,根据初中数学可知此时xq-py=1时答案最优,所以我们得到xq-p*y=1,因此可求出x,y的解的方程,然后我们发现题中要求是分母最大是m的所有分数,因此x,y<m,及求出y在<m下的最大解,当求出y时,x也可以求出,这样就解出了x,y,同理,也可求出在p/q左边的分数。
下面是代码

#include
#include
#include
#include
#define ll long long
using namespace std;
ll T,nn,p,q;
void exgcd(ll a,ll b,ll &x,ll &y){
    if(!b){
        x=1,y=0;
        return;
    }
    exgcd(b,a%b,x,y);
    ll t=x;
    x=y,y=t-(a/b)*y;
}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%lld%lld%lld",&nn,&p,&q);
        ll n,m,x,y;
        exgcd(p,-q,m,n);
        ll b=min((nn-m)/q,(nn-n)/p);
        x=-n,y=-m,n+=b*p,m+=b*q;
        if((n<1)||(n>nn)||(m<1)||(m>nn)||(m==1))
            puts("Yuri is master");
        ll bb=min((nn-y)/q,(nn-x)/p);
        y+=q*bb,x+=p*bb;
        if((x<1)||(x>nn)||(y<1)||(y>nn))
            puts("Yuri is master");
        if(m*x

你可能感兴趣的:(题解,牛客)