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; }