spoj FINFRAC

题目链接:http://www.spoj.com/problems/FINFRAC/

题目大意:给你四个数a,b,c,d让你求最小的q,和对应的最小的p(q最小的情况下),使得a/b<p/q<c/d

题目分析:参考博客:http://blog.csdn.net/gogdizzy/article/details/8727386

    设计知识点连分数,简要说下:我们进行分类讨论

    (1)a>=b  我们设k为a整除b的值,那么a/b-k<p/q-k<c/d-k ,即(a-bk)/b<(p-qk)/q<(c-dk)/d,然后递归求解

    (2)a<b,再次进行分类讨论

        <1> c>d  那么p=q=1为我们所求的解

        <2> c<=d 那么我们把式子进行翻转去求解d/c<q/p<b/a.

    另外,如果我们知道了a,b,q的话,p的最小值应为q*b/a+1


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>

using namespace std;
typedef long long LL;

LL find(LL a,LL b,LL c,LL d)
{
	if (a>=b)
	{
		LL k=a/b;
		return find(a-k*b,b,c-k*d,d);
	}
	else
	{
		if (c>d) return 1;
		else return find(d,c,b,a)*d/c+1;
	}
 } 
int main()
{
	LL a,b,c,d,p,q;
	while (scanf("%lld %lld %lld %lld",&a,&b,&c,&d)==4)
	{
		q=find(a,b,c,d);
		p=q*a/b+1;
		printf("%lld/%lld\n",p,q);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值