POJ 2653(线段相交)

来源:互联网 发布:淘宝开店怎么收费标准 编辑:程序博客网 时间:2024/03/29 15:26

题目:题目链接

题目的意思就是说,给你n个线段,把这些线段随机丢到坐标平面上,问你最后在最上面的线段有哪些?就是一个判断线段相交的问题

分析:

我们可以拿一条线段,然后枚举后面的线段,如果有一条线段和当前的线段相交,就直接break掉,如果后面的线段都没有和其相交的话,就把其编号保存下来,最后输出编号就OK了,代码:

#include <iostream>#include <cstdio>#include <string>#include <string.h>#include <map>#include <vector>#include <cstdlib>#include <cmath>#include <algorithm>#include <queue>#include <set>#include <stack>using namespace std;#define N 100000+5const double eps = 1e-10;struct node{    double x, y;} Pointa[N],Pointb[N];int cross(node a, node b, node c, node d){    if(min(a.x, b.x) > max(c.x, d.x) || min(a.y, b.y) > max(c.y, d.y)            || min(c.x, d.x) > max(a.x, b.x) || min(c.y, d.y) > max(a.y,b.y))        return 0;    double h, i, j, k;    h = (b.x - a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);    i = (b.x - a.x)*(d.y-a.y)-(b.y-a.y)*(d.x-a.x);    j = (d.x - c.x)*(a.y-c.y)-(d.y-c.y)*(a.x-c.x);    k = (d.x - c.x)*(b.y-c.y)-(d.y-c.y)*(b.x-c.x);    if(( h*i <= eps) && (j*k <= eps))        return 1;    else return 0;}int xp[N];int main(){    int n;    while(scanf("%d", &n))    {        memset(xp, 0, sizeof(xp));        if(!n)            break;        for(int i = 0; i < n; ++i)            scanf("%lf%lf%lf%lf", &Pointa[i].x, &Pointa[i].y, &Pointb[i].x, &Pointb[i].y);        for(int i = 0; i < n; ++i)        {            for(int j = i+1; j < n; ++j)            {                if(cross(Pointa[i], Pointb[i], Pointa[j], Pointb[j]))                {                    xp[i] = 1;                    break;                }            }        }        int ans[N];        memset(ans, 0, sizeof(xp));        int cnt = 0;        for(int i = 0; i < n; ++i)        {            if(!xp[i])                ans[cnt++] = i+1;        }        printf("Top sticks: ");        for(int i = 0; i < cnt-1; ++i)            printf("%d, ", ans[i]);        printf("%d.\n", ans[cnt-1]);    }    return 0;}

努力努力...