CodeForces - 97B_Superset_分治
2018-01-27 19:51
351 查看
题意
给出平面上 n 个点的坐标(最多 1e4 个),要往其上增加若干点,使得加点后,平面上任意两点至少满足下列三条件之一:1。两点横坐标相同
2。两点纵坐标相同
3。以两点为对角的矩形中(含边线),至少含义一个其他点。
要求新加入点不超过 2e5。
思路
首先找到中间那个点,即 mid = (1 + n) / 2。过这个点作一条垂直于 x 轴的直线,不在这条直线上的其他点在这条直线上的正投影都增加到平面上。增加之后,直线上任意一点和平面上现有的任意一点构成的点对必满足上述条件。并且,任意一对被直线分隔开的点,也必定满足上述条件。不被直线分隔的点对仍可能不满足条件。所以,题目转化为确保任意两点之间至少有一条这样的直线分隔。用分治的思想解决。
经过第一步之后,原问题实际上分成了两个与原问题相同的子问题:直线左边的点 和 直线右边的点。情况与原问题相同。所以,递归地过每一个子问题中间的点作垂直于 x 轴的直线,将子问题中的其他点的投影加入,将子问题继续细分直到不可分。
这样最多加入 nlogn 个节点,必小于 2e5。完美解决。
链接
https://vjudge.net/contest/177348#problem/J代码
#include<iostream> #include<cstdio> #include<algorithm> #include<set> using namespace std; const int maxn = 1e4 + 10; typedef pair<int, int> P; int n; P A[maxn]; set<P> se; set<P>::iterator it; void dfs(int l, int r) { int mid = (l + r) >> 1; int x = A[mid].first; for(int i = l; i <= r; i++) se.insert(P(x, A[i].second)); if(l < mid) dfs(l, mid); if(mid < r) dfs(mid + 1, r); } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d %d", &A[i].first, &A[i].second); sort(A + 1, A + n + 1); dfs(1, n); cout << se.size() << endl; for(it = se.begin(); it != se.end(); it++) cout << it->first << " " << it->second << endl; return 0; }
相关文章推荐
- Superset CodeForces - 97B(分治基础)
- [codeforces] 97B Superset || 平面分治
- CodeForces 97B Superset (分治)
- Codeforces 97B Superset 平面分治
- Codeforces 97B Superset 平面分治
- Codeforces 888G XOR MST(分治)
- Codeforces 437D The Child and Zoo - 树分治 - 贪心 - 并查集 - 最大生成树
- codeforces 434B B. Nanami's Digital Board(分治)
- Codeforces 526F Pudding Monsters - CDQ分治 - 桶排序
- codeforces 868D 分治哈希
- CodeForces 448C - Painting Fence(分治)
- CodeForces 97B Superset
- Codeforces 873 D Merge Sort 【分治】
- Codeforces 888G Xor-MST - 分治 - 贪心 - Trie
- CodeForces 161D [Distance in Tree] 点分治
- Codeforces 321C Ciel the Commander 树分治
- Codeforces 868F - Yet Another Minimization Problem (分治DP,莫队)
- CodeForces 526F Pudding Monsters (分治)
- Codeforces_448C 分治
- Codeforces 848C (cdq分治)