背景
90分代码
AC代码
小杉终于进入了天堂。他看到每个人都带着一双隐形翅膀,他也想要。
(小杉是怎么看到的?……)
描述
天使告诉小杉,每只翅膀都有长度,两只翅膀的长度之比越接近黄金分割比例,就越完美。
现在天使给了小杉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
这题比较神奇
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
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 }
上面的方法不知道哪里有问题
只好换一种原理
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
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 }