您的位置:首页 > 其它

spoj FINFRAC

2016-02-19 01:06 239 查看
题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: