HDU2150 Pipe【计算几何】

Pipe
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2908 Accepted Submission(s): 1198

Problem Description
经过激烈的争夺,Lele终于把那块地从Yueyue的手里抢了回来。接下来,Lele要开始建造他的灌溉系统。

通过咨询Lele的好友——化学系的TT,Lele决定在田里挖出N条沟渠,每条沟渠输送一种肥料。

每条沟渠可以看作是一条折线,也就是一系列线段首尾连接而成(除了第一条线段开头和最后一条线段的结尾)。由于沟渠很细,你可以忽略掉它的宽度。

由于不同的肥料之间混合会发生化学反应,所以修建的沟渠与沟渠之间不能相交。

现在TT给Lele画了一些设计图,Lele请你判断一下设计图中的沟渠与沟渠之间是否有相交。

Input
本题目包含多组测试,请处理到文件结束(EOF)。
每组测试的第一行有一个正整数N(0<N<30),表示管道的数目。接下来给出这N条管道的信息。
对于每条管道,第一行是一个正整数K(0<K<100),表示这条管道是由K个端点组成。
接下来的K行给出这K个端点信息。每个端点占一行,用两个整数X和Y(0<X,Y<1000)分别表示这个端点的横坐标和纵坐标的值。

Output
对于每组测试,如果该测试管道与管道之间有相交的话,输出"Yes",否则输出"No"。

Sample Input
2
2
0 0
1 1
2
0 1
1 0
2
2
0 0
1 1
2
1 0
2 1
2
3
0 0
1 1
2 1
2
2 0
3 0

Sample Output
Yes
No
No

Author
Linle

Source
ACM程序设计期末考试——2008-01-02(3 教417)

问题链接HDU2150 Pipe
问题简述:(略)
问题分析:计算几何题,判定线段相交,用暴力来解决。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* HDU2150 Pipe */

#include <bits/stdc++.h>

using namespace std;

#define EPS 1e-10

struct Point {double x, y;};

int inter(Point a, Point b, Point c, Point 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);
    return h * i <= EPS && j * k <= EPS;
}

#define N 30
#define K 100
int num[N];
Point pi[N][K];

int main()
{
    int n;
    while (~scanf("%d", &n)) {
        for (int i = 0; i < n; i++) {
            scanf("%d", &num[i]);
            for (int j = 0; j < num[i]; j++)
                scanf("%lf%lf", &pi[i][j].x, &pi[i][j].y);
        }

        int flag = 0;
        for (int i = 0; i < n; i++)
            for (int j = i + 1; j < n; j++)
                for (int k = 0; k < num[i] - 1; k++)
                    for (int l = 0; l < num[j] - 1; l++)
                        if (inter(pi[i][k], pi[i][k + 1], pi[j][l], pi[j][l +1])) {
                            flag = 1;
                            break;
                        }

        printf(flag ? "Yes\n" : "No\n");
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值