zoukankan      html  css  js  c++  java
  • 牛客网比赛226C-数学题-题解

    题目地址【IN

    这个题目可谓非常神啊,博主做了好久,QAQ

    题意简述

    给你一个数的范围nn,和分数pqfrac{p}{q},保证p,qp,q互质且小于等于nn,请求出最大的x1y1<pq,1x1,y1nfrac{x_1}{y_1}<frac{p}{q},1leq x_1,y_1leq n和最小的x2y2>pq,1x2,y2nfrac{x_2}{y_2}>frac{p}{q},1leq x_2,y_2leq n

    数据范围:所有数字都在long longlong long范围内。


    我们观察原式x1y1<pqfrac{x_1}{y_1}<frac{p}{q},我们可以发现x1+kpy1+kq<pqfrac{x_1+kp}{y_1+kq}<frac{p}{q}是仍然成立的,因为原式变形后得到x1q<y1px_1q<y_1p,而现在得到x1q+kpq<y1p+kpqx_1q+kpq<y_1p+kpq,是一样的,所以不变。

    由于都是整数,所以y1px1q1y_1p-x_1qgeq 1,所以要取极值,就是y1px1q=1y_1p-x_1q=1,又因gcd(p,q)=1gcd(p,q)=1gcd(p,q)1gcd(p,q)|1的,所以一定有整数解,那么我们用exgcd m exgcd求出一组x1,y1x_1,y_1的解。

    然后我们发现x1y1<x1+kpy1+kqfrac{x_1}{y_1}<frac{x_1+kp}{y_1+kq}的:

    证明:

    通过相减我们可以得到:

    x1y1x1+kpy1+kq=x1y1+kx1qx1y1ky1py1(y1+kq)=k(x1qy1p)y1(y1+kq)frac{x_1}{y_1}-frac{x_1+kp}{y_1+kq}=frac{x_1y_1+kx_1q-x_1y_1-ky_1p}{y_1(y_1+kq)}=frac{k(x_1q-y_1p)}{y_1(y_1+kq)}

    x1y1<pqfrac{x_1}{y_1}<frac{p}{q}可知x1q<y1px_1q<y_1p的,所以最后k(x1qy1p)y1(y1+kq)frac{k(x_1q-y_1p)}{y_1(y_1+kq)}为负数,所以x1y1<x1+kpy1+kqfrac{x_1}{y_1}<frac{x_1+kp}{y_1+kq},那么我们要求最大的,就是在nn的限制内加最多的kpkpkqkq


    对于另一个式子x2y2>pqfrac{x_2}{y_2}>frac{p}{q},我们同理可得x2kpy2kq>pqfrac{x_2-kp}{y_2-kq}>frac{p}{q},然后又可以得到x2kpy2kq<x2y2frac{x_2-kp}{y_2-kq}<frac{x_2}{y_2}的,所以我们求出一组x2,y2x_2,y_2然后尽量在nn的范围内减去即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int M=1e5+10;
    int T;
    ll n,p,q;
    ll P;
    ll exgcd(ll a,ll b,ll &x,ll &y){
    	if(!b){x=1;y=0;return a;}
    	ll t=exgcd(b,a%b,y,x);
    	y-=x*(a/b);return t;
    }
    int main(){
    	for(scanf("%d",&T);T--;){
    		scanf("%lld%lld%lld",&n,&p,&q);
    //		if(p==n||(p==1&&q==n)){puts("Yuri is master");continue;}
    		ll x,y,t1,t2,inv_x,inv_y;
    		exgcd(p,-q,x,y);//求最小x,y满足条件(这里好像x,y写反了)
    		inv_x=-x;inv_y=-y;//减去
    		t1=min((n-x)/q,(n-y)/p);//最多加的加多少
    		t2=min((n+x)/q,(n+y)/p);//最多减的加多少
    		x+=t1*q;y+=t1*p;
    		inv_x+=t2*q;inv_y+=t2*p;//加上
    		if(x*inv_y<y*inv_x)swap(x,inv_x),swap(y,inv_y);//判断大小
    		if(y!=0)printf("%lld %lld
    ",y,x);//判断有无解
    		else puts("Yuri is master");
    		if(inv_x!=0)printf("%lld %lld
    ",inv_y,inv_x);
    		else puts("Yuri is master");
    		//输出
    	}
    	return 0;
    }
    
    
    
  • 相关阅读:
    Go中的结构实现它的的写法注意事项
    Go语言中的struct的初始化。
    python中的number类型
    python的类型
    今天起,每天记录python等语言的编程心得和体会
    destoon 下apache伪静态排除目录规则
    如何进行数据库设计?
    Spring IOC知识点
    SpringBoot框架:集成Security完成认证鉴权
    CentOS 7 本地安装kubernetes
  • 原文地址:https://www.cnblogs.com/VictoryCzt/p/10053389.html
Copyright © 2011-2022 走看看