原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=2150
一:分析
有n条管道,每条管道是由若干点组成的折线,判断这n条管道是否是互不相交。
二:AC代码
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct Node
{
double x, y;
};
Node node[35][105];
int num[105];
int n;
/* 求出向量AB与向量AC的差积,返回0代表共线 */
double cross(Node A, Node B, Node C)
{
return (B.x - A.x)*(C.y - A.y) - (C.x - A.x)*(B.y - A.y);
}
/* 判断线段AB与线段CD是否相交,相交返回true */
bool intersect(Node A, Node B, Node C, Node D)
{
if (min(A.x, B.x) <= max(C.x, D.x) &&
min(C.x, D.x) <= max(A.x, B.x) &&
min(A.y, B.y) <= max(C.y, D.y) &&
min(C.y, D.y) <= max(A.y, B.y) &&
cross(A, B, C)*cross(A, B, D) < 0 &&
cross(C, D, A)*cross(C, D, B) < 0)
return true;
return false;
}
/* 遍历所有线段,判断是否相交,只要有一个相交,返回true */
bool solve()
{
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
for (int ii = 1; ii < num[i]; ii++)
for (int jj = 1; jj < num[j]; jj++)
if (intersect(node[i][ii - 1], node[i][ii], node[j][jj - 1], node[j][jj]))
return true;
return false;
}
int main()
{
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", &node[i][j].x, &node[i][j].y);
}
if (n == 1)
printf("No\n");
else
{
if (solve())
printf("Yes\n");
else
printf("No\n");
}
}
return 0;
}