vijos 隐形的翅膀

Posted 心之所向 素履以往

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vijos 隐形的翅膀相关的知识,希望对你有一定的参考价值。

背景

小杉终于进入了天堂。他看到每个人都带着一双隐形翅膀,他也想要。

(小杉是怎么看到的?……)

描述

天使告诉小杉,每只翅膀都有长度,两只翅膀的长度之比越接近黄金分割比例,就越完美。

现在天使给了小杉N只翅膀,小杉想挑出一对最完美的。

格式

输入格式

每组测试数据的
第一行有一个数N(2<=N<=30000)
第二行有N个不超过1e5的正整数,表示N只翅膀的长度。

20%的数据N<=100

输出格式

对每组测试数据输出两个整数,表示小杉挑选出来的一对翅膀。

注意,比较短的在前,如果有多对翅膀的完美程度一样,请输出最小的一对。

样例1

样例输入1

4
2 3 4 6

样例输出1

2
3

限制

每个测试点1s

提示

你可以认为黄金分割比就是0.6180339887498949

来源

lolanv

 

这题比较神奇

技术分享
 1 /*
 2     枚举一个数 a[i] 
 3     除以黄金比 得到 t=a[i]/gold
 4     找到 与 t相差最小的数 
 5 */
 6 #include<cstdio>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define gold 0.6180339887498949
10 #define MAXN 30010
11 
12 using namespace std;
13 
14 int n,a[MAXN],Lx,Ry;
15 
16 double minn=1000000.0;
17 
18 inline void read(int&x) {
19     x=0;int f=1;char c=getchar();
20     while(c>9||c<0) {if(c==-) f=-1;c=getchar();}
21     while(c>=0&&c<=9) {x=(x<<1)+(x<<3)+c-48;c=getchar();}
22     x=x*f;
23 }
24 
25 inline bool cmp(int a,int b) {
26     return a<b;
27 }
28 
29 inline double abs(double x) {
30     if(x<0) return -x;
31     return x;
32 }
33 
34 int main() {
35     read(n);
36     for(int i=1;i<=n;i++) read(a[i]);
37     sort(a+1,a+1+n,cmp);
38     for(int i=1;i<=n;i++) {
39         if(a[i]==0) continue;
40         double p=a[i]/gold;
41         int l=i,r=n,mid,k;
42         while(l<=r) {
43             mid=(l+r)>>1;
44             if(a[mid]>p) r=mid-1,k=r;
45             else l=mid+1;
46         }
47         if(a[k]==0) continue;
48         double temp=abs((double)a[i]/a[k]-gold); 
49         if(temp<minn) {
50             minn=temp;
51             Lx=a[i];
52             Ry=a[k];
53         }
54     }
55     printf("%d\n%d\n",Lx,Ry);
56     return 0;
57 } 
90分代码

上面的方法不知道哪里有问题

只好换一种原理

技术分享
 1 /*
 2     枚举两个数 
 3     计算黄金比
 4     取最优值 
 5 */
 6 #include<cstdio>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define gold 0.6180339887498949
10 #define MAXN 30010
11 
12 using namespace std;
13 
14 int n,a[MAXN],Lx,Ry;
15 
16 double minn=1000000.0;
17 
18 inline void read(int&x) {
19     x=0;int f=1;char c=getchar();
20     while(c>9||c<0) {if(c==-) f=-1;c=getchar();}
21     while(c>=0&&c<=9) {x=(x<<1)+(x<<3)+c-48;c=getchar();}
22     x=x*f;
23 }
24 
25 inline bool cmp(int a,int b) {
26     return a<b;
27 }
28 
29 inline double abs(double x) {
30     if(x<0) return -x;
31     return x;
32 }
33 
34 inline bool judge(int x,int y) {
35     double GOLD=(double)a[x]/(double)a[y];
36     if(GOLD<gold) {
37         if(gold-GOLD<minn) {
38             minn=gold-GOLD;
39             Lx=a[x];
40             Ry=a[y];
41         }
42         return 1;
43     }
44     if(GOLD>gold) {
45         if(GOLD-gold<minn) {
46             minn=GOLD-gold;
47             Lx=a[x];
48             Ry=a[y];
49         }
50         return 0;
51     }
52 }
53 
54 int main() {
55     read(n);
56     for(int i=1;i<=n;i++) read(a[i]);
57     sort(a+1,a+1+n,cmp);
58     for(int i=1;i<=n;i++) {
59         if(a[i]==0) continue;
60         double p=a[i]/gold;
61         int l=i,r=n,mid,k;
62         while(l<=r) {
63             mid=(l+r)>>1;
64             if(judge(i,mid)) r=mid-1;
65             else l=mid+1;
66         }
67     }
68     printf("%d\n%d\n",Lx,Ry);
69     return 0;
70 } 
AC代码

 

以上是关于vijos 隐形的翅膀的主要内容,如果未能解决你的问题,请参考以下文章

二分查找(隐形的翅膀vijos1237)

IMXRT1061“智能手环”为工业制造插上“隐形的翅膀”

平凡中成就不平凡

有感而发,随笔记录

vijos P1223

《梦中的婚礼》怎么弹