codevs 2190 有理逼近

2190 有理逼近

 

 时间限制: 1 s
 空间限制: 32000 KB
 题目等级 : 黄金 Gold
 
题目描述 Description

对于一个素数P,我们可以用一系列有理分数(分子、分母都是不大于N的自然数)来逼近sqrt(p),例如P=2,N=5的时候:1/1<5/4<4/3<sqrt(2)<3/2<5/3<2/1。
任 务 :
给定P、N(N>sqrt(p)),求X、Y、U、V,使x/y<sqrt(p)<u/v且x/y与sqrt(p)之间、sqrt(p)与u/v之间都不能再插入满足题意的有理分数。

输入描述 Input Description

输入文件的第一行为P、N

输出描述 Output Description

输出文件只有一行,格式为“X/Y U/V”。注意,答案必须是既约的,也就是说分子、分母的最大公约数必须等于1。

样例输入 Sample Input

样例1:
2 5
样例2:
5 100

样例输出 Sample Output

样例1:
4/3 3/2

样例2:
38/17 85/38

数据范围及提示 Data Size & Hint

 P、N<30000

——————————————————我是分割线————————————————————————

思路好题

因为要求(i/j)≈sqrt(p)

所以转化为:对于每一个i,求j≈(i/sqrt(p))

这样就极大地减小了循环量。

最后一定要注意精度!注意精度!注意精度!

(不明白精度怎么办的请移步:http://www.cnblogs.com/SBSOI/p/5957321.html

 1 /*
 2     Problem:
 3     OJ:
 4     User:    S.B.S.
 5     Time:
 6     Memory:
 7     Length:
 8 */
 9 #include<iostream>
10 #include<cstdio>
11 #include<cstring>
12 #include<cmath>
13 #include<algorithm>
14 #include<queue>
15 #include<cstdlib>
16 #include<iomanip>
17 #include<cassert>
18 #include<climits>
19 #include<functional>
20 #include<bitset>
21 #include<vector>
22 #include<list>
23 #include<map>
24 #define F(i,j,k) for(int i=j;i<=k;i++)
25 #define M(a,b) memset(a,b,sizeof(a))
26 #define FF(i,j,k) for(int i=j;i>=k;i--)
27 #define maxn 10001
28 #define inf 0x3f3f3f3f
29 #define maxm 1001
30 #define mod 998244353
31 #define eps 1e-7
32 //#define LOCAL
33 using namespace std;
34 int read(){
35     int x=0,f=1;char ch=getchar();
36     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
37     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
38     return x*f;
39 }
40 int n,m,p;
41 int cur1,cur2;
42 double mn=inf;
43 inline int gcd(int a,int b)
44 {
45     return b ? gcd(b,a%b) : a;
46 }
47 int main()
48 {
49 //    std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y;
50     #ifdef LOCAL
51     freopen("data.in","r",stdin);
52     freopen("data.out","w",stdout);
53     #endif
54     p=read();n=read();
55     FF(i,n,1){
56         F(j,floor(i/sqrt(p)),ceil(i/sqrt(p)))
57         {
58             if(i==j||j<=0||j>n) continue;
59             if(sqrt(p)>(double)i/j&&sqrt(p)-(double)i/j<=mn)
60             {
61                 cur1=i;cur2=j;
62                 mn=sqrt(p)-(double)i/j;
63             }
64         }
65     }
66     int aa=gcd(cur1,cur2);
67     printf("%d/%d ",cur1/aa,cur2/aa);
68 //    cout<<cur1/aa<<"/"<<cur2/aa<<" ";
69     mn=inf;
70     FF(i,n,1){
71         F(j,floor(i/sqrt(p)),ceil(i/sqrt(p)))
72         {
73             if(i==j||j<=0||j>n) continue;
74             if(sqrt(p)<(double)i/j&&(double)i/j-sqrt(p)<=mn)
75             {
76                 cur1=i;cur2=j;
77                 mn=(double)i/j-sqrt(p);
78             }
79         }
80     }
81     int bb=gcd(cur1,cur2);
82     printf("%d/%d\n",cur1/bb,cur2/bb);
83 //    cout<<cur1/bb<<"/"<<cur2/bb<<endl;
84     return 0;
85 }
rational

 

posted @ 2016-10-14 17:07  SBSOI  阅读(422)  评论(0编辑  收藏  举报