1. 程式人生 > >CRB and Farm HDU - 5408

CRB and Farm HDU - 5408

unique blank bsp .net targe opera vector view ros

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 }
View Code

CRB and Farm HDU - 5408