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;
}