紫书 第8章 UVa1411 Ants 巨人与鬼
来源:互联网 发布:mac有哪些好玩的游戏 编辑:程序博客网 时间:2024/05/03 20:08
题意:给出平面上n个白点n个黑点,要求两两配对,且配对所连线段没有交点。
解题方法:
由于只需要一种配对方法,从直观上来说本题一定是有解的。由于每一个巨人和鬼都需
要找一个目标,不妨先给“最特殊”的巨人或鬼寻找“搭档”。
考虑y坐标最小的点(即最低点)。如果有多个这样的点,考虑最左边的点(即其中最
左边的点),则所有点的极角在范围[0,π)内。不妨设它是一个巨人,然后把所有其他点按照
极角从小到大的顺序排序后依次检查。
情况1:第一个点是鬼,那么配对完成,剩下的巨人和鬼仍然是一样多,而且不会和这
一条线段交叉,如图8-6(a)所示。
情况2:第一个点是巨人,那么继续检查,直到已检查的点中鬼和巨人一样多为止。找
到了这个“鬼和巨人”配对区间后,只需要把此区间内的点配对,再把区域外的点配对即可,
如图8-6(b)所示。这个配对过程是递归的,好比棋盘覆盖中一样。会不会找不到这样的配
对区间呢?不会的。因为检查完第一个点后鬼少一个,而检查完最后一个点时鬼多一个,而
巨人和鬼的数量差每次只能改变1,因此“从少到多”的过程中一定会有“一样多”的时候。
代码如下:
#include <bits/stdc++.h>using namespace std;const int N = 110;int n;struct Point{ int x, y; Point(){} Point(int x, int y) : x(x), y(y){} double angle(const Point &p) const{ return atan2(y - p.y, x - p.x); } bool operator < (const Point &rhs) const{ return y < rhs.y || (y == rhs.y && x < rhs.x); } void read(){ scanf("%d%d", &x, &y); }};struct Node{ Point p; int id; double ang; bool operator <(const Node &rhs) const{ return ang < rhs.ang; } void getangle(const Point &p0){ ang = p.angle(p0); } int type() const{ return id <= n ? 1 : -1; }}p[N * 2];int ans[N * 2];void solve(int l, int r){ if(l > r) return ; int pos = l; for(int i = l + 1; i <= r; i++){ if(p[i].p < p[pos].p){ pos = i; } } swap(p[pos], p[l]); int cnt = p[l].type(); for(int i = l + 1; i <= r; i++){ p[i].getangle(p[l].p); } sort(p + l + 1, p + r + 1); for(int i = l + 1; i <= r; i++){ cnt += p[i].type(); if(cnt == 0){ ans[p[l].id] = p[i].id; ans[p[i].id] = p[l].id; solve(l + 1, i - 1); solve(i + 1, r); return ; } }}int main(){ while(scanf("%d", &n) != EOF) { memset(ans, 0, sizeof(ans)); for(int i = 1; i <= 2 * n; i++){ p[i].p.read(); p[i].id = i; } solve(1, n * 2); for(int i = 1; i <= n; i++){ printf("%d\n", ans[i] - n); } } return 0;}
0 0
- 紫书 第8章 UVa1411 Ants 巨人与鬼
- UVa1411-Ants
- 问题8.3.3 巨人与鬼 UVa 1411 Ants(分治)
- 巨人与鬼问题
- 巨人与鬼
- 分治法,最小权完美匹配(巨人和鬼,Ants,uva 1411)
- 紫书_第八章_高效算法设计_8.3.3——巨人与鬼
- 算法竞赛入门经典 8.3.3巨人与鬼
- 算法竞赛入门经典 8.3.3 巨人与鬼
- 巨人和鬼问题
- Ants
- Ants
- Ants
- Ants
- Ants
- Ants
- Ants
- Ants
- 有关RXjava retryWhen
- sduacm16级寒假训练 贪心二分
- 验证码无刷新验证(AJAX技术)
- xtrabackup
- 加分二叉树_洛谷1040_dp
- 紫书 第8章 UVa1411 Ants 巨人与鬼
- iOS开发 如何获取前几个月月份数组
- QT 激活窗口
- 二维数组
- Centos7 安装Oracle11gR2全过程详解
- C++学习笔记之异常处理
- 模拟作业调度-先来先服务算法
- 三维数组
- QT PlainTextEdit 获取标记的文字