ZOJ-3862-Intersection【贪心】
来源:互联网 发布:计算机语言翻译软件 编辑:程序博客网 时间:2024/05/17 03:03
3862-Intersection
Time Limit: 3 Seconds Memory Limit: 131072 KB
Edward has 2n points on the plane conveniently labeled with 1,2,…,2n. Each point is connected exactly with another point by a segment.
Edward finds that some segments intersecting with some others. So he wants to eliminate those intersections with the following operation: choose two points i and j (1 ≤ i, j ≤ 2n) and swap their coordinates.
swap point 2 and 3
For example, Edward has 4 points (0, 0), (0, 1), (1, 1), (1, 0). Point 1 is connected with point 3 and point 2 is connected with 4. Edward can choose to swap the coordinates of point 2 and point 3.
Edward wants to know whether it is possible to use at most n + 10 operations to achieve his goal.
No two points coincide and no three points are on the same line.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
The first line contains an integer n (1 ≤ n ≤ 100000).
Each of the following 2n lines contains 2 integers xi, yi which denotes the point (xi, yi). (|xi|, |yi| ≤ 109).
Each of the following n lines contains 2 integers ai, bi (1 ≤ ai, bi ≤ 2n, ai ≠ bi), which means point ai and point bi are connected by a segment.
The sum of values n for all the test cases does not exceed 300000.
Output
For each test case, print a line containing an integer m, indicating the number of operations needed. You must assure that m is no larger than n + 10. If you cannot find such a solution, just output “-1” and ignore the following output.
In the next m lines, each contains two integers i and j (1 ≤ i, j ≤ 2n), indicating an operation, separated by one space.
If there are multiple solutions, any of them is accepted.
Sample Input
1
2
0 0
0 1
1 1
1 0
1 3
2 4
Sample Output
1
2 3
题目链接:ZOJ-3862
题目大意:给出2 * n个点的位置,以及n条线段,每个点属于且仅属于一条线段。问,如何交换点,使得每条线段互不相交。交换m次需<n+10
题目思路:贪心。首先将这个点,由x小到大排序,分别记录位置编号为1,2,3…. 2 * n。 我们可以将1和2相连,因为这两个点在最左边,所以不会和其他点纠缠。同理3和4连….这样的操作最多n次。所以一定能存在合理的答案。
注意:两个点交换位置时:1. 记录答案 ;2.交换两个点的no值以及vis值
以下是代码:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <algorithm>#include <map>using namespace std;struct node{ int x,y,no;}p[200005]; //用于记录各个点的位置以及编号map <int,int> mp; //mp[i] = j 表示 i点与j点相连bool cmp1(node a,node b) //以x小的先排{ if (a.x != b.x) return a.x < b.x; else return a.y < b.y;}int last[200005]; //记录交换的答案int vis[200005]; //vis[i] = j 表示 编号为i的点 在排好序的序列中排第几位int main(){ int t; cin >> t; while(t--) { memset(last,0,sizeof(last)); memset(vis,0,sizeof(vis)); mp.clear(); int n; scanf("%d",&n); for (int i = 0; i < 2 * n; i++) { scanf("%d%d",&p[i].x,&p[i].y); p[i].no = i + 1; } for (int i = 0; i < n; i++) { int a,b; scanf("%d %d",&a,&b); mp[a] = b; mp[b] = a; } int k = 0; int ans = 0; sort(p,p + n*2,cmp1); for (int i = 0; i < n * 2; i++) { vis[p[i].no] = i; } for (int i = 0; i < n * 2; i += 2) { int u = p[i].no; int v = p[i + 1].no; if (mp[u] == v) continue; else { int u_con = mp[u]; last[k++] = v; last[k++] = u_con; swap(p[i + 1].no,p[vis[u_con]].no); ans++; swap(vis[v],vis[u_con]); } } printf("%d\n",ans); for (int i = 0; i < k; i += 2) { printf("%d %d\n",last[i],last[i + 1]); } } return 0;}
- ZOJ-3862-Intersection【贪心】
- ZOJ 3862 Intersection【贪心】【几何】【模拟】
- ZOJ 3862 Intersection
- ZOJ 3862 Intersection (dijkstra)
- zoj 3862 Intersection (技巧题)
- zoj 3862 Intersection(枚举)
- zoj 贪心
- 【贪心】ZOJ
- ZOJ 1199 Point of Intersection
- zoj 1199 Point of Intersection
- ZOJ 1199Point of Intersection
- ZOJ 3198 Intersection of Two Sets
- zoj 3198 Intersection of Two Sets
- ZOJ 3198 Intersection of Two Sets
- ZOJ 1199 Point of Intersection(平面几何)
- zoj 2229 贪心..
- ZOJ 3197 (贪心)
- ZOJ 3508 贪心
- 用js改变embed标签的src值
- 如何点亮一盏LED灯
- 1016-算法设计acm
- Java中的Copy-On-Write容器
- 设计模式学习笔记——备忘录模式
- ZOJ-3862-Intersection【贪心】
- Opengl学习资料
- Xcode升级导致插件无法使用和点击skip bundle后怎么重新加载插件
- 重学数据结构系列之——二叉排序树
- TCP中的三次握手和四次挥手
- 函数指针(之一)——在排序算法中的应用
- Ural 1223.Chernobyl’ Eagle on a Roof
- Android Studio 打包、生成jks密钥、签名Apk、多渠道打包
- 【UVa】10360 - Rat Attack