UVaLive4043 UVa1411 Ants 巨人与鬼
2016-02-18 09:34
106 查看
题意:给出平面上n个白点n个黑点,要求两两配对,且配对所连线段没有交点。
法一:暴力
随机一个初始方案,枚举任意两条线段如果有交点就改一下。
效率其实挺好的。
法二:二分图最佳完美匹配
显然没有交点的方案是所有线段的长度和最小的方案,将边权构造为欧几里德距离即可,$O(n^4)$的算法效率远不及法一,$O(n^3)$与法一持平。
法三:分治
这是紫书上介绍的方法,每次找出一个最下最左的点,将其他的点相对于这个点进行极角排序,按极角序扫描,当白点和黑点一样多时(算上最下最左那个点),将第一个点和最后一个点配对,递归处理剩下的两部分。时间复杂度大概是$O(n^2\log{n})$的?效率最高。
分治算法
法一:暴力
随机一个初始方案,枚举任意两条线段如果有交点就改一下。
效率其实挺好的。
法二:二分图最佳完美匹配
显然没有交点的方案是所有线段的长度和最小的方案,将边权构造为欧几里德距离即可,$O(n^4)$的算法效率远不及法一,$O(n^3)$与法一持平。
法三:分治
这是紫书上介绍的方法,每次找出一个最下最左的点,将其他的点相对于这个点进行极角排序,按极角序扫描,当白点和黑点一样多时(算上最下最左那个点),将第一个点和最后一个点配对,递归处理剩下的两部分。时间复杂度大概是$O(n^2\log{n})$的?效率最高。
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> using namespace std; const int N = 100 + 10; #include<cmath> 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); } }; int n; 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) { 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) == 1) { for(int i = 1; i <= (n << 1); i++) { p[i].p.read(); p[i].id = i; } solve(1, n << 1); for(int i = 1; i <= n; i++) { printf("%d\n", ans[i] - n); } } return 0; }
分治算法
相关文章推荐
- CI-持续集成(2)-软件工业“流水线”技术实现
- 文件IO(系统IO和标准IO)
- Android开发艺术探索读书笔记(二)
- 2015年十大测试工具你认识几个?
- 面试题1:落单的数
- MyCat源码分析系列之——配置信息和启动流程
- MyCat源码分析系列之——前后端验证
- click
- MySQL数据类型和属性设置
- 在rhel7中搭建openstack kilo
- unity shader 固定管线实例(四) 渲染不一样的背面
- 机器学习中的神经网络Neural Networks for Machine Learning:Lecture 9 Quiz
- 剖析设计模式编程中C#对于组合模式的运用
- 深入理解Java中的HashMap的实现原理
- 程序员的编程能力层次模型
- jmeter ---测试TCP服务器/模拟发送TCP请求
- Android开发艺术探索读书笔记(一)
- Aspose.Words 替换word值和保存打印
- 解决水平ListView在ScrollView中出现的滑动冲突
- 解决水平ListView在ScrollView中出现的滑动冲突