[codeforces] 97B Superset || 平面分治
原题
给出一个平面的一些点,让你添加点,使得所有点对满足以下三个要求中的一个:
1、在一个水平面上
2、在一个竖直线上
3、以这两个点为对角的矩形内包含有其他点
输出一种可行解
因为只需要可行解,且只满足任意一种就够了,所以:
对于所在平面,把所有的点映射到中线的点加入set,并由中线将其分为两半进行递归,这样保证了满足条件。
#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;
pair<int, int> point[10001];
set< pair<int, int> > all;
int n;
void dfs(int l, int r)
{
int mid=(l+r)>>1,mid_x=point[mid].first;
for (int i=l;i<=r;i++)
all.insert(make_pair(mid_x, point[i].second));
if (l<mid) dfs(l,mid-1);
if (mid<r) dfs(mid+1,r);
}
int main()
{
scanf("%d", &n);
for (int i=0;i<n;i++)
scanf("%d%d",&point[i].first,&point[i].second);
sort(point,point+n);
dfs(0,n-1);
int p=all.size();
printf("%d
",p);
for (set < pair<int,int> > ::iterator i=all.begin();i!=all.end();i++)
printf("%d %d
", i->first, i->second);
return 0;
}