题目链接:http://codeforces.com/contest/1027/problem/C
题意: 给出几个数字,一个数字只能用一次,取4个数字构成矩形,要求周长的平方除以面积尽可能的小;
思路:
大多数人应该都能得出 b/a+a/b这个公式((2*(a+b))^2/(a*b),这个公式化简得到),只要矩形的长和宽 a,b 能让 b/a+a/b尽可能小就行了;最初得到的结论就是,a和b尽可能相等就能最小,因为b/a+a/b >= 2,当a == b的时候;所以贪心的策略就是排序,取差值最小的两个数;但是这个结论是错误,这里有个例子 1305 4406 8664 这三个数中取两个当长和宽,如果取第一个第二个的话,所得的结果比取第二个和第三个要大;所以正确的贪心应该是直接依次取两个数,求出最小的 b/a+a/b;如果a和b差值较大的话,假设a < b;那么 a/b+b/a的结果主要取决与 b/a;但是并不是说b和a的差值越小,b/a的值就越小。因为b和a的差值还要通过a来进行比较;比如说 1305 和 4406的差值是 3101 而 4406 和8664 的差值是 4258 ,显然差值前者要小于后者,但是前者的3101是1305的3倍,而4258是4406的1倍不到;但是做题的时候,一直感觉只有差值越小,值就越小;
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<sstream>
#include<vector>
#include<string>
#include<set>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0);
int read(){
int r=0,f=1;char p=getchar();
while(p>'9'||p<'0'){if(p=='-')f=-1;p=getchar();}
while(p>='0'&&p<='9'){r=r*10+p-48;p=getchar();}return r*f;
}
typedef long long ll;
const int Maxn = 1e6+10;
const long long LINF = 1e18;
const int INF = 0x3f3f3f3f;
int a[10005],b[Maxn];
int main (void)
{
IOS;
int t,n,tmp;
cin >> t;
while (t--) {
cin >> n;
int m = 0;
memset(a,0,sizeof(a));
for (int i = 0; i < n; ++i) {
cin >> tmp;
if(a[tmp]) b[m++] = tmp;
a[tmp] = (a[tmp]+1)%2;
}
sort(b,b+m);
int pos;
double mi = INF;
for (int i = 1; i < m; ++i) {
if(mi > b[i]/(b[i-1]*1.0)+b[i-1]/(b[i]*1.0)) {
mi = b[i]/(b[i-1]*1.0)+b[i-1]/(b[i]*1.0);
pos = i;
}
}
cout << b[pos-1] << " " << b[pos-1] << " " << b[pos] << " " << b[pos] << endl;
}
return 0;
}