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 }