加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ PKU 2653 计算几何 线段相交

(2010-07-19 14:35:30)
标签:

poj

pku

2653

it

分类: 计算几何

题目描述:

一个人往平面上扔木条(看做线段),告诉你扔的位置(两个端点的坐标),后扔的可能会把以前扔的覆盖掉。扔完n个后,问你没有被覆盖的木条有哪些。

解题报告:

每扔一个,从上一次扔后的顶端木条开始遍历(不超过1000个),如果被刚扔的覆盖了(相交),就删掉这个顶端木条。遍历完后,注意刚扔的木条肯定也是顶端木条,加入顶端木条集合。

复杂度:扔n个,但是顶端木条不超过1000个,所以是O(1000*n)

代码如下:

#include<iostream>
#include<cmath>
using namespace std;
struct pint
{
    double x, y;
};
int eps(double xx)
{
    if (fabs(xx) <= 0.00001) return 0;
    else if (xx > 0) return 1;
    else return -1;
}
double direction(pint p1, pint p2, pint p3)
{
    return (p3.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (p3.y - p1.y);
}
bool online(pint p1, pint p2, pint p3)
{
    return (p3.x >= min(p1.x, p2.x) && p3.x <= max(p1.x, p2.x) && p3.y >= min(p1.y, p2.y) && p3.y <= max(p1.y, p2.y));
}
bool insect(pint p1, pint p2, pint p3, pint p4)
{
    double d1 = direction(p3, p4, p1);
    double d2 = direction(p3, p4, p2);
    double d3 = direction(p1, p2, p3);
    double d4 = direction(p1, p2, p4);
    if (eps(d1) * eps(d2) < 0 && eps(d3) * eps(d4) < 0) return true;
    else if (eps(d1) == 0 && online(p3, p4, p1)) return true;
    else if (eps(d2) == 0 && online(p3, p4, p2)) return true;
    else if (eps(d3) == 0 && online(p1, p2, p3)) return true;
    else if (eps(d4) == 0 && online(p1, p2, p4)) return true;
    return false;
}
struct line
{
    pint a, b;
    int id;
}x[1010][2], temp;
int n, cnt, from, to, len;
int main()
{
    while(scanf("%d", &n) && n)
    {
        cnt = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%lf%lf%lf%lf", &temp.a.x, &temp.a.y, &temp.b.x, &temp.b.y);
            temp.id = i + 1;
            from = i % 2, to = (i + 1) % 2, len = cnt; cnt = 0;
            for(int j = 0; j < len; j++)
                if (!insect(temp.a, temp.b, x[j][from].a, x[j][from].b))
                    x[cnt++][to] = x[j][from];
            x[cnt++][to] = temp;
        }
        printf("Top sticks: %d", x[0][to].id);
        for(int i = 1; i < cnt; i++)
            printf(", %d", x[i][to].id);
        printf(".\n");
    }
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有