poj 3565

来源:互联网 发布:淘宝苏绣屏风价格 编辑:程序博客网 时间:2024/06/05 23:46

题目概述

平面中有白点和黑点各N个,各编号1到N,给定他们的坐标x,y,问如何连接黑点与白点使得所有连线互不相交
任何三点不共线,不存在重合点

时限

5000ms/15000ms

输入

第一行正整数N,其后N行,每行两个整数x,y,描述白点坐标,其后N行,每行两个整数x,y,描述黑点坐标,输入到EOF为止

限制

1<=N<=100;-10000<=x,y<=10000

输出

每组数据输出在N行中,每行一个数,为与白点匹配的黑点序号,按白点序号升序排列,答案可能有多种,输出任意一组均可

样例输入

5
-42 58
44 86
7 28
99 34
-13 -59
-47 -44
86 74
68 -75
-68 60
99 -60

样例输出

4
2
1
5
3

讨论

计算几何?额是这么想的,借用一点冒泡排序的思想,但几乎就是暴力解决,思想就是,只要相交,就交换,直到所有线都不相交为止
为了对抗暴力,采用了一点极端写法,其实是不值得提倡的,不过也算杀入排行第一页了
这个题正确解法应该是用km算法吧,二分图一直没动,暂时也写不了

题解状态

164K,16MS,C++,1350B

题解代码

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define INF 0x3f3f3f3f#define MAXN 102#define memset0(a) memset(a,0,sizeof(a))#define EPS 1e-8short N;//每种点总数 不超过100short x[MAXN], y[MAXN], x2[MAXN], y2[MAXN], match[MAXN];//白点和黑点的坐标 及其匹配关系 坐标绝对值不超过10000 匹配关系不超过100inline int xp(int x1, int y1, int x2, int y2, int x3, int y3)//向量积 可能上溢 都用int{    return (x1 - x2)*(y3 - y2) - (y1 - y2)*(x3 - x2);}inline bool intersect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)//相交 这两个函数需要频繁调用 都是内联{    int xp1 = xp(x3, y3, x1, y1, x2, y2), xp2 = xp(x4, y4, x1, y1, x2, y2), xp3 = xp(x1, y1, x3, y3, x4, y4), xp4 = xp(x2, y2, x3, y3, x4, y4);    return(xp1 > 0 && xp2 < 0 || xp1 < 0 && xp2>0) && (xp3>0 && xp4 < 0 || xp3 < 0 && xp4>0);//按题目要求只有内交 省去了后面的判断 同时为了提速 直接以符号判断异号而非从前按积的符号判断}void fun(){    for (int p = 0; p < N; p++)        scanf("%d%d", &x[p], &y[p]);//input    for (int p = 0; p < N; p++) {        scanf("%d%d", &x2[p], &y2[p]);//input        match[p] = p;//顺手初始化匹配    }    bool f = 1;//flag 表示存在相交    while (f) {        f = 0;//初始化为没有相交        for (int p = 0; p < N; p++)            for (int i = p + 1; i < N; i++)                if (intersect(x[p], y[p], x2[match[p]], y2[match[p]], x[i], y[i], x2[match[i]], y2[match[i]])) {                    f = 1;                    match[p] ^= match[i];//为了提速而没用swap函数 用了这个老办法                    match[i] ^= match[p];                    match[p] ^= match[i];                }    }    for (int p = 0; p < N; p++)        printf("%d\n", match[p] + 1);//output}int main(void){    //freopen("vs_cin.txt", "r", stdin);    //freopen("vs_cout.txt", "w", stdout);    while (~scanf("%d", &N))//input        fun();}

EOF

0 0
原创粉丝点击