C - 2D Plane 2N Points (贪心,考虑多因素贪心)
题目来源(川渝联谊赛正式赛):https://atcoder.jp/contests/arc092/tasks/arc092_a?lang=en
//
题意:给出n个红点和蓝点的(x,y)坐标,如果一个红点的x和y坐标都小于蓝点,红点和蓝点可以形成友好对。最多能组成几对朋友?请注意,一个点不能属于多个对。
//
思路:“当时我想的是贪心,用远的蓝点配对远的红点,确实也是这样,但是我当时只考虑了x坐标”,x和y的坐标都是需要考虑的,题解是对蓝点的x升序排序,红点的
x降序排序,是先用近的蓝点去跑大(x,y远)的红点,前面两个continue相当于两个筛子,如果没有被continue,说明有x,y比较拦截的,和vis标记,伸缩后不存在不满足条件和重复,
当前的较大的红色满足小于较小的蓝色,下面看是否可以伸缩更优(更大)的红。 !!!然后又进一步贪心,如果有y更大的红点且没有被筛掉,那就刷新更优的该红点。
//
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=109;
vector<int>vis(N,0);
struct Nod{
int x,y;
}H[N],L[N];
bool cmp(Nod a,Nod b){
if(a.x==b.x) return a.y>b.y;
return a.x>b.x;
}
bool cmp1(Nod a,Nod b){
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
signed main()
{
int n,x,y;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x>>y;
H[i].x=x,H[i].y=y;
}
for(int i=1;i<=n;i++){
cin>>x>>y;
L[i].x=x,L[i].y=y;
}
sort(H+1,H+1+n,cmp);
sort(L+1,L+1+n,cmp1);
int p=-1;
for(int i=1;i<=n;i++){//蓝:先是小的
p=-1;
for(int j=1;j<=n;j++){//红:先是大的
if(vis[j]) continue;
if(H[j].x>=L[i].x || H[j].y>=L[i].y) continue;//当前的较大的红色满足小于较小的蓝色,下面看是否可以伸缩更优(更大)的红
//有x,y比较拦截的,和vis标记,伸缩后不存在不满足条件和重复
if(p==-1) p=j;
else if(p!=-1 && H[j].y>H[p].y) p=j;
}
if(p!=-1) vis[p]=1;
}
cout << accumulate(vis.begin(), vis.end(), 0ll);
return 0;
}
浙公网安备 33010602011771号