Vijos隐形的翅膀
背景
小杉终于进入了天堂。他看到每个人都带着一双隐形翅膀,他也想要。
(小杉是怎么看到的?……)
描述
天使告诉小杉,每只翅膀都有长度,两只翅膀的长度之比越接近黄金分割比例,就越完美。
现在天使给了小杉N只翅膀,小杉想挑出一对最完美的。
格式
输入格式
每组测试数据的 第一行有一个数N(2<=N<=30000) 第二行有N个不超过1e5的正整数,表示N只翅膀的长度。
20%的数据N<=100
输出格式
对每组测试数据输出两个整数,表示小杉挑选出来的一对翅膀。
注意,比较短的在前,如果有多对翅膀的完美程度一样,请输出最小的一对。
样例1
样例输入1
4
2 3 4 6
Copy
样例输出1
2
3
Copy
限制
每个测试点1s
提示
你可以认为黄金分割比就是0.6180339887498949
分析
我们可以将所有数据从小到大快排,然后对于数组中的每个数a[i],去除以黄金分割比可以得到一个数,再在数组中找和所得数相近的数,用找到的数除以a[i],最后找和黄金分割比最相近的一组数。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath> using namespace std;
const double xyz = 0.6180339887498949;
int n;
double a[30005];
double ans = 9999999999.0;
int x, y;
int search(double e, int p)
{
int l = p + 1, r = n;
while (l <= r)
{
int mid = (l + r) / 2;
if (a[mid] <= e)
l = mid + 1;
else
r = mid - 1;
}
double w = fabs(a[l] - e);
double b = fabs(a[l - 1] - e);
double c = fabs(a[l + 1] - e);
if (w < b && w < c)
return l;
else if (b < w && b < c)
return l - 1;
else
return l + 1;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; i++)
{
double t = (a[i] / (xyz));
int k = search(t, i);
double temp = fabs(a[i] / a[k] - xyz);
if (temp < ans)
{
ans = temp;
x = a[i];
y = a[k];
}
}
cout << x << endl
<< y << endl;
return 0;
}