「Codeforces 1027C」Minimum Value Rectangle

题目链接:https://codeforces.com/contest/1027/problem/C


Description

  有 N N 条线段,选择 4 条线段组成一个矩形,记 P P 为矩形的周长,S 为矩形的面积,求使得 P2S P 2 S 最小的 4 4 条线段(保证有解)。

  T 组数据, 1T106 1 ⩽ T ⩽ 10 6 4N106 4 ⩽ N ⩽ 10 6 1ai104 1 ⩽ a i ⩽ 10 4


Solution

  设 4 4 条线段为 a,a,b,b (ab),则有 P=2(a+b) P = 2 ⋅ ( a + b ) S=ab S = a b ,得

P2S=4a2+4b2+8abab=4(ab+ba)+8 P 2 S = 4 a 2 + 4 b 2 + 8 a b a b = 4 ( a b + b a ) + 8

  易知我们只需要最小化 ba b a 即可(千万注意此处 ba b ⩾ a )。

分类讨论

  1. 如果有 4 4 条相等的线段,肯定选取这 4 条。
  2. 否则将数量不小于 2 2 的线段从小到大排序,贪心选择相邻的线段。将当前的 a,b 和已知的较优解 a,b a , b 比较得出更优解。

  注意精度问题!我们可以将判定条件 ba<ba b ′ a ′ < b a 转化为 ab<ab a b ′ < a ′ b 即可防止精度问题。

  时间复杂度 Θ(TNlogamax) Θ ( T N log ⁡ a max )


Code

#include <cstdio>
#include <cctype>
#include <map>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
inline char in() {
    static char buf[10001],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,10000,stdin),p1==p2)?EOF:*p1++;
}
template <class Tp> void read(register Tp &s) {
    s=0;
    register bool neg=0;
    register char c;
    while(!isdigit(c=in())) if(c=='-') neg=1;
    while(s=(s<<3)+(s<<1)+c-48,isdigit(c=in()));
    s=(neg?-s:s);
}

int T,n,a[1000005];
std::map<int,int> cnt;
int main() {
    for(read(T);T;--T) {
        cnt.clear();
        read(n);
        int t,m=0;
        FOR(i,1,n) read(t),cnt[t]++;
        bool flg=0;
        for(std::map<int,int>::iterator it=cnt.begin();it!=cnt.end();++it) {
            if((*it).second>=2) a[++m]=(*it).first;
            if((*it).second>=4) {
                flg=1;
                int ans=(*it).first;
                printf("%d %d %d %d\n",ans,ans,ans,ans);
                break;
            }
        }
        if(flg) continue;
        int x=a[1],y=a[2];
        FOR(i,3,m) if(x*a[i]<a[i-1]*y) x=a[i-1],y=a[i];
        printf("%d %d %d %d\n",x,x,y,y);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值