H. Twin Buildings(排序,详细证明)

. 2 Ⅰ.在一块地内选两个矩阵就是这块地面积除以2

. a b ( b > = a ) Ⅱ.在两块地上分别选a*b的矩阵(b>=a)

[ q , w ] , [ e , r ] ( w > = q , r > = e ) 设这两块地属性是[q,w],[e,r]且(w>=q,r>=e)

a = m i n ( q , e ) , b = m i n ( w , r ) 那么a=min(q,e),b=min(w,r)

, a , b 由此可见选择边界一定最优而且不管怎么选,最优的a,b都来自边界

那么我们按照最长边大到小排序,由于b一定来自最长边

所以我们只要对于所有的较长边作为b,选择最大的a,就覆盖了所有可能的答案

, w , q 因为按照最长边大到小排序,设每块地较长边是w,较短边是q

w w , 前面的w一定覆盖了当前的w,所以只能和前面的地匹配

, q , q a 由此一来,只要记录前面最长的q,和现在的q取小就是a了

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
struct p{
	ll l,r;
}a[maxn];
ll n;
bool com(p a,p b){
	return a.r>b.r;
}
int main()
{
	cin >> n;
	for(int i=1;i<=n;i++)
	{
		cin >> a[i].l >> a[i].r;
		if( a[i].l> a[i].r)
			swap(a[i].l,a[i].r);
	}
	sort(a+1,a+1+n,com);
	ll maxx=a[1].l,ans=a[1].l*a[1].r,now;
	for(int i=2;i<=n;i++)
	{
		ans = max(ans,a[i].l*a[i].r);
		now = min(maxx,a[i].l);//当前的l和以前最大的l取最小
		ans=max(ans,2*now*a[i].r);
		maxx = max(maxx,a[i].l); 
	}
	if(ans%2==0)	printf("%lld.0\n",ans/2);
	else	printf("%lld.5\n",ans/2);
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/106872637