TYVJ P1077 有理逼近 Label:坑,tle的好帮手 不懂

描述

对于一个素数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之间都不能再插入满足题意的有理分数。

输入格式

输入文件的第一行为P、N,其中 P、N<30000。

输出格式

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

测试样例1

输入

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

输出

样例1: 
4/3 3/2 

样例2: 
38/17 85/38

代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cmath>
 5 #include<queue>
 6 #include<cstring>
 7 #include<algorithm>
 8 using namespace std;
 9 int des_int,P,N,a,b,ans[10]={1,1,1,1,1,1,1,1,1,1};
10 double des;
11 
12 int check(int i,int j,double x){
13      return (fabs( des-double(ans[i])/double(ans[j]) ) > fabs( des-x ));
14 }
15 
16 void xiao(){//ans1~2
17     for(int i=des_int-1;i<=N;i++){
18         int flag=0;
19         for(int j=1;j<=i;j++){
20             double x=double(i)/double(j);
21             if(x>des) continue;
22             if(check(1,2,x)){
23                 double k1=(double(ans[1])/double(ans[2])),k2=x;
24                 bool fl=(k1==k2);
25                 if(fl) continue;
26                 ans[1]=i;ans[2]=j;
27             }
28             else{
29                 flag=1;break;
30             }
31         }
32         if(flag==1) continue;
33     }
34 }
35 
36 void da(){//ans3~4
37     for(int i=des_int+1;i<=N;i++){
38         int flag=0;
39         for(int j=i-1;j>=1;j--){
40             double x=double(i)/double(j);
41             if(x<des) continue;
42             if(check(3,4,x)){
43                 if(fabs( des-double(ans[3])/double(ans[4]) )== fabs( des-x )) continue;
44                 ans[3]=i;ans[4]=j;
45             }
46             else{
47                 flag=1;break;
48             }
49         }
50         if(flag==1) continue;
51     }
52 }
53 int main(){
54 //    freopen("01.txt","r",stdin);
55     scanf("%d %d",&P,&N);
56     des=sqrt(double(P));
57     des_int=des;
58     xiao();
59     da();
60     
61     printf("%d/%d %d/%d\n",ans[1],ans[2],ans[3],ans[4]);
62     return 0;
63 }

穷尽今生所学,T掉2个点

上看不懂的别人代码:

 1 #include <math.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4  
 5 int main(int argc, char **argv)
 6 {
 7     int i, j;
 8     int p, n;
 9     int a, b, c, d;
10     int beg, end;
11     double s, max = 0, min = 300000, t;
12     scanf("%d%d", &p, &n);
13     s = sqrt(p);
14     for(i = 1; i <= n; i++){
15         beg = i * s - 1;
16         end = beg + 1;
17         if(beg <= 0){
18             beg = 1;
19         }
20         if(end > n){
21             end = n;
22         }
23         for(j = beg; j <= end; j++){
24             t = (double)(j) / i;
25             if(t < s && t > max){
26                 a = j, b = i;
27                 max = t;
28             }
29         }
30     }
31     for(i = 1; i <= n; i++){
32         beg = i * s;
33         end = beg + 1;
34         if(beg <= 0){
35             beg = 0;
36         }
37         if(end > n){
38             end = n;
39         }
40         for(j = beg; j <= end; j++){
41             t = (double)(j) / i;
42             if(t > s && min > t){
43                 c = j, d = i;
44                 min = t;
45             }
46         }
47     }
48     printf("%d/%d %d/%d\n", a, b, c, d);
49     return 0;
50 }

---------------我是猥琐的分割线---------------

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cmath>
 5 #include<queue>
 6 #include<cstring>
 7 #include<algorithm>
 8 using namespace std;
 9 int des_int,P,N,a,b,ans[10]={1,1,1,1,1,1,1,1,1,1};
10 double des;
11 
12 int check(int i,int j,double x){
13      return (fabs( des-double(ans[i])/double(ans[j]) ) > fabs( des-x ));
14 }
15 
16 void xiao(){//ans1~2
17     for(int i=des_int-1;i<=N;i++){
18         int flag=0;
19         for(int j=1;j<=i;j++){
20             double x=double(i)/double(j);
21             if(x>des) continue;
22             if(check(1,2,x)){
23                 double k1=(double(ans[1])/double(ans[2])),k2=x;
24                 bool fl=(k1==k2);
25                 if(fl) continue;
26                 ans[1]=i;ans[2]=j;
27             }
28             else{
29                 flag=1;break;
30             }
31         }
32         if(flag==1) continue;
33     }
34 }
35 
36 void da(){//ans3~4
37     for(int i=des_int+1;i<=N;i++){
38         int flag=0;
39         for(int j=des_int/i+1000;j>=1;j--){
40             double x=double(i)/double(j);
41             if(x<des) continue;
42             if(check(3,4,x)){
43                 if(fabs( des-double(ans[3])/double(ans[4]) )== fabs( des-x )) continue;
44                 ans[3]=i;ans[4]=j;
45             }
46             else{
47                 flag=1;break;
48             }
49         }
50         if(flag==1) continue;
51     }
52 }
53 int main(){
54 //    freopen("01.txt","r",stdin);
55     scanf("%d %d",&P,&N);
56     des=sqrt(double(P));
57     des_int=des;
58     xiao();
59     da();
60     
61     printf("%d/%d %d/%d\n",ans[1],ans[2],ans[3],ans[4]);
62     return 0;
63 }

39行调了个阈值成功骗分,主要都是da()函数耗的时间,也就没多想,+500有点危险,+100绝对过不了

想法来源于(能跑这么久的数肯定很大,分母也就没必要那么大了!!!)

posted @ 2016-08-23 17:18  Radiumlrb  阅读(210)  评论(0编辑  收藏  举报