zoukankan      html  css  js  c++  java
  • 【BZOJ2187】fraction(类欧几里得算法)

    点此看题面

    大致题意: 给定两个分数(frac ab)(frac cd),求(frac pq)满足(frac ab<frac pq<frac cd),且在(q)尽量小的前提下(p)尽量小。

    前言

    这是怎么想到类欧几里得算法的。。。

    我这种蒟蒻只会第一种情况,第二种情况都没想到。

    类欧几里得算法

    • (frac ab)(frac cd)之间存在整数时,必然选择其中最小的整数。
    • (a=0)时,条件就只有(frac pq<frac cd),也就是(q>frac{dp}c)。显然(p=1)(q)可以取到最小值,此时(q=lfloorfrac dc floor+1)
    • (a<b)时,我们对所有数取倒数,得到(frac dc<frac qp<frac ba),递归做即可。
    • (age b)时,我们只保留(frac ab)的小数部分,令(t=lfloorfrac ab floor),得到(frac{a\%b}b<frac{p-qt}q<frac{c-dt}d),同样递归做即可。

    于是这道题就做完了,理解起来其实并不难,但也太难想到了。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define swap(x,y) (x^=y^=x^=y)
    using namespace std;
    int a,b,c,d;
    I void Get(CI a,CI b,CI c,CI d,int& x,int& y)//类欧几里得算法
    {
    	if(a/b+1<=(c-1)/d) return (void)(x=a/b+1,y=1);if(!a) return (void)(x=1,y=d/c+1);//存在整数;a=0
    	a<b?(Get(d,c,b,a,x,y),swap(x,y)):(Get(a%b,b,c-(a/b)*d,d,x,y),x+=y*(a/b));//a<b;a≥b(注意修改得到正确的x,y)
    }
    int main()
    {
    	RI x,y;W(scanf("%d%d%d%d",&a,&b,&c,&d)==4) Get(a,b,c,d,x,y),printf("%d/%d
    ",x,y);
    	return 0;
    }
    
  • 相关阅读:
    C++动态链接库实践
    解决:linux eclipse 对‘dlopen’未定义的引用, 对‘xxx’未定义的引用
    bsd linux macosx solaris windows
    字节码加载执行原理
    JNI原理
    TODO: Java虚拟机 初始化过程
    mysql replaceinto VS insertinto
    centos7 搭建测试环境
    java 传值
    vue中使用sass 做减法计算
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ2187.html
Copyright © 2011-2022 走看看