代码改变世界

SPOJ FINFRAC Finding Fractions

2013-05-20 16:32  bootstar  阅读(283)  评论(0编辑  收藏  举报

Finding Fractions

这个题目开始考虑了良久,想到用法雷数列解,但是数据范围很大,显然时间复杂度不可忍受。然后看到了大牛的神奇解法ORZ。。。

寻找p,q满足条件:a/b<p/q<c/d,并且要求使q尽量小,p尽量小。首先假设求解出q的值,那么我们便可以得到p的值,q*a<b*p所以p = q*a/b+1.那么问题就转化为求解q.

考虑a/b,c/d的关系:

1. a/b<1<c/d,此时q是1.

2.a/b>1 且a/b<floor(a/b)+1<c/d,此时q为1.

3.a/b<c/d<1,此时可转化为b/a>q/p>d/c>1

4.其他情况:a/b<p/q<c/d ,设k = a/b那么有(a - b*k)/b < (p-q*k)/q<(c-d*k)/d<1。

然后将这些过程综合一下就可以了.

 

#include <stdio.h>
#include <iostream>
using namespace std;
typedef long long LL;

LL dfs(LL a, LL b, LL c, LL d){
    LL k = a/b;
    a -= b*k, c-=d*k;
    if(c > d) return 1;
    if(a==0) return d/c+1;
    return dfs(d, c, b, a)*d/c+1;
}

int main(){
    LL a, b, c, d;
    while(cin>>a>>b>>c>>d){
        LL y = dfs(a, b, c, d);
        cout<<y*a/b+1<<"/"<<y<<endl;
    }
    return 0;
}