CRB and Farm HDU - 5408
Posted yijiull
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CRB and Farm HDU - 5408相关的知识,希望对你有一定的参考价值。
CRB and Farm
HDU - 5408题意:给一个n个点的大凸包,再给k个内部点,问能否选择不超过2k个大凸包上的点使得所选点围成的凸包完全包含内部的k个点.
首先明确一定是存在的
可以先对内部的k个点求一个凸包,然后选一个凸包内的点A,求A与凸包上的各点形成的射线与大凸包的交点.则交点所在线段的两端就是所选点.
关键在于判断射线与线段相交.
//判断射线a1--b1是否与线段a2--b2相交 bool Intersection(Point a1, Point b1, Point a2, Point b2) { double c1 = Cross(b1-a1, a2-a1), c2 = Cross(b1-a2, b2-a2); double c3 = Cross(b1-b2, a1-b2); return dcmp(c1)<0 && dcmp(c2)<0 && dcmp(c3)<0 || dcmp(c1)>0 && dcmp(c2)>0 && dcmp(c3)>0;
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf = 0x3f3f3f3f; 4 const double eps = 1e-8; 5 const int maxn = 2e5+10; 6 7 struct Point { 8 double x,y; 9 Point (double x = 0, double y = 0) : x(x), y(y) {} 10 }; 11 typedef Point Vector; 12 Vector operator + (Vector a, Vector b) { 13 return Vector (a.x + b.x, a.y + b.y); 14 } 15 Vector operator * (Vector a, double s) { 16 return Vector (a.x * s, a.y * s); 17 } 18 Vector operator / (Vector a, double p) { 19 return Vector (a.x / p, a.y / p); 20 } 21 Vector operator - (Point a, Point b) { 22 return Vector (a.x - b.x, a.y - b.y); 23 } 24 bool operator < (Point a, Point b) { 25 return a.x < b.x || (a.x == b.x && a.y < b.y); 26 } 27 int dcmp (double x) { 28 if(fabs(x) < eps) return 0; 29 return x < 0 ? -1 : 1; 30 } 31 bool operator == (const Point &a, const Point &b) { 32 return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; 33 } 34 35 double Dot(Vector a, Vector b) { 36 return a.x * b.x + a.y * b.y; 37 } 38 double Length (Vector a) { 39 return sqrt(Dot(a, a)); 40 } 41 double Angle (Vector a, Vector b) { 42 return acos(Dot(a, b) / Length(a) / Length(b)); 43 } 44 double Cross (Vector a, Vector b) { 45 return a.x * b.y - a.y * b.x; 46 } 47 //判断射线a1--b1是否与线段a2--b2相交 48 bool Intersection(Point a1, Point b1, Point a2, Point b2) { 49 double c1 = Cross(b1-a1, a2-a1), c2 = Cross(b1-a2, b2-a2); 50 double c3 = Cross(b1-b2, a1-b2); 51 return dcmp(c1)<0 && dcmp(c2)<0 && dcmp(c3)<0 || 52 dcmp(c1)>0 && dcmp(c2)>0 && dcmp(c3)>0; 53 } 54 //凸包 55 int ConvexHull(Point *p, int n, Point *ch) { 56 int m = 0; 57 sort(p, p+n); 58 for(int i = 0; i < n; i++) { 59 while(m > 1 && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0) m--; //去掉在边上的点 60 ch[m++] = p[i]; 61 } 62 int k = m; 63 for(int i = n-2; i >= 0; i--) { 64 while(m > k && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0) m--; // 65 ch[m++] = p[i]; 66 } 67 if(m > 1) m--; 68 return m; 69 } 70 71 Point p1[maxn], p2[maxn], ch[maxn]; 72 73 int main() { 74 int t; 75 //freopen("in.txt", "r", stdin); 76 scanf("%d", &t); 77 while(t--){ 78 int n; 79 scanf("%d", &n); 80 for(int i = 0; i < n; i++) { 81 scanf("%lf %lf", &p1[i].x, &p1[i].y); 82 } 83 p1[n] = p1[0]; 84 int k; 85 scanf("%d", &k); 86 for(int i = 0; i < k; i++){ 87 scanf("%lf %lf", &p2[i].x, &p2[i].y); 88 } 89 int cnt = ConvexHull(p2, k, ch); 90 Point o = ch[0]; 91 vector<int> v; 92 for(int i = 1; i < cnt; i++) { 93 o = (o+ch[i])/2; 94 } 95 int id = 0; 96 for(int i = 0; i < cnt; i++){ 97 while(!Intersection(o, ch[i], p1[id], p1[id+1])) id=(id+1)%n; 98 v.push_back(id); 99 v.push_back((id+1)%n); 100 } 101 sort(v.begin(), v.end()); 102 cnt = unique(v.begin(), v.end()) - v.begin(); 103 puts("Yes"); 104 printf("%d\n", cnt); 105 for(int i = 0; i < cnt; i++) printf("%d%c", v[i]+1, i==cnt-1?‘\n‘:‘ ‘); 106 } 107 }
以上是关于CRB and Farm HDU - 5408的主要内容,如果未能解决你的问题,请参考以下文章
hdu5406 CRB and Apple dp+两个LIS
HDU 5407 CRB and Candies(LCM +最大素因子求逆元)
HDU - 5411 CRB and Puzzle 矩阵快速幂