题目链接
AtCoder:https://arc073.contest.atcoder.jp/tasks/arc073_c
洛谷:https://www.luogu.org/problemnew/show/AT2557
Solution
不难的贪心,注意到全局最小值一定在四个值中出现两次以上,我们枚举出现在那些值,由于颜色本质相同,一共两种情况:
- 蓝色取到最大值,红色取到最小值,那么对于每个二元组把小的染红大的染蓝一定最优。
- 否则我们假设蓝色同时取到了最大值和最小值,我们的目的就是把红色的区间最小化。
可以考虑承接上面做法,先按红色从小到大排序,然后从小到大把颜色对调,顺便记下区间的最小值,这个感性理解一下就是前面整些大的值以贴合后面的值使得区间最小。
由于中间排了遍序,复杂度(O(nlog n))。
#include<bits/stdc++.h>
using namespace std;
#define int long long
void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('
');}
#define lf double
#define ll long long
const int maxn = 2e5+10;
const int inf = 1e9;
const lf eps = 1e-8;
int mx,mn=1e9,n,mn1=1e9,mx1;
struct data{
int x,y;
bool operator < (const data &rhs) const {return x<rhs.x;}
}a[maxn];
signed main() {
read(n);
for(int i=1;i<=n;i++) {
read(a[i].x),read(a[i].y);if(a[i].x>a[i].y) swap(a[i].x,a[i].y);
mx=max(mx,a[i].y),mn=min(mn,a[i].x);
mn1=min(mn1,a[i].y),mx1=max(mx1,a[i].x);
}sort(a+1,a+n+1);
int ans=(mx-mn1)*(mx1-mn),res,mn2=a[1].y,mx2=a[1].y;
res=max(a[1].y,a[n].x)-min(a[1].y,a[2].x);
for(int i=2;i<=n;i++) {
mn2=min(mn2,a[i].y),mx2=max(mx2,a[i].y);
if(i!=n) res=min(res,max(mx2,a[n].x)-min(mn2,a[i+1].x));
}ans=min(ans,res*(mx-mn));
write(ans);
return 0;
}