凸多边形 | ||||||
| ||||||
Description | ||||||
已知一个凸多边形A(包含n个点,点按照顺时针给出),和一个点集B(包含m个点),请判断这m个点是否都严格在凸多边形A内部。 | ||||||
Input | ||||||
输入包含多组测试数据。 对于每组测试数据: 第1行,包含一个整数n (3?≤ n ≤?105)代表着凸多边形A的点的数量。 接下来n行每行包含一个坐标(x, 第n + 接下来m行每行包含一个坐标(x, 处理到文件结束 | ||||||
Output | ||||||
对于每组测试数据: 第1行,如果点集B都严格在凸多边形A内,输出YES,否则输出NO。 | ||||||
Sample Input | ||||||
4 -10 -10 -10 10 10 10 10 -10 3 0 0 1 1 2 2 4 -10 -10 -10 10 10 10 10 -10 3 100 100 1 1 2 2 | ||||||
Sample Output | ||||||
YES NO | ||||||
Author | ||||||
齐达拉图@HRBUST |
思路:二分+叉积
代码:
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 using namespace std;
6
7 const int maxn = 100005;
8 typedef long long LL;
9
10 struct Node
11 {
12 LL x;
13 LL y;
14 }node1[maxn], node2[maxn];
15
16 LL cross(Node n0, Node n1, Node n2)
17 {
18 return (n1.x - n0.x)*(n2.y - n0.y) - (n2.x - n0.x)*(n1.y - n0.y);
19 }
20
21 int main()
22 {
23 int n, m;
24 while(scanf("%d",&n) != EOF)
25 {
26 for(int i = 0; i < n; i++)
27 scanf("%lld %lld",&node1[i].x, &node1[i].y);
28 scanf("%d",&m);
29 for(int i = 0; i < m; i++)
30 scanf("%lld %lld",&node2[i].x, &node2[i].y);
31 bool ans = true;
32 for(int i = 0; i < m; i++)
33 {
34 if(cross(node1[0], node1[1], node2[i]) >= 0 || cross(node1[0], node1[n-1], node2[i]) <= 0)
35 {
36 ans = false;
37 break;
38 }
39 int front = 1, end = n - 1;
40 while(end - front != 1)
41 {
42 int mid = (front + end)>>1;
43 if(cross(node1[0], node1[mid], node2[i]) >= 0)
44 end = mid;
45 else
46 front = mid;
47 }
48 if(cross(node1[front], node2[i], node1[end]) <= 0)
49 {
50 ans = false;
51 break;
52 }
53 }
54 if(ans)
55 printf("YES\n");
56 else
57 printf("NO\n");
58 }
59 return 0;
60 }
hlg1429凸多边形 二分+叉积,码迷,mamicode.com
时间: 2024-10-06 01:19:12