标签:als bool splay fast 折线 can link any mem
Time Limit: 3 second(s) | Memory Limit: 32 MB |
Once there was a lazy monkey in a forest. But he loved banana too much. One day there was a storm in the jungle and all the bananas fell from the trees. The monkey didn‘t want to lose any of the bananas. So, he wanted to find a banana such that he can eat that and he can also look after the other bananas. As he was lazy, he didn‘t want to move his eyes too wide. So, you have to help him finding the banana from where he can look after all the bananas but the degree of rotating his eyes is as small as possible. You can assume that the position of the bananas can be modeled as 2D points.
Here a banana is shown, from where the monkey can look after all the bananas with minimum eye rotation.
Input starts with an integer T (≤ 13), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 105) denoting the number of bananas. Each of the next n lines contains two integers x y (-109 ≤ x, y ≤ 109) denoting the co-ordinate of a banana. There can me more than one bananas in the same co-ordinate.
For each case, print the case number and the minimum angle in degrees. Errors less than 10-6 will be ignored.
Sample Input |
Output for Sample Input |
2 1 4 4 4 0 0 10 0 10 10 2 1 |
Case 1: 0 Case 2: 45.0000000 |
Dataset is huge. Use faster I/O methods.
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstdio> 5 #include<cstring> 6 using namespace std; 7 const int maxn = 1e5 + 5; 8 const double pi = acos(-1.0); 9 const double eps = 1e-8; 10 int sgn(double x) { 11 if (fabs(x) < eps)return 0; 12 if (x < 0)return -1; 13 else return 1; 14 } 15 typedef struct point { 16 double x, y; 17 point() { 18 19 } 20 point(double a, double b) { 21 x = a; 22 y = b; 23 } 24 point operator -(const point &b) const { 25 return point(x - b.x, y - b.y); 26 } 27 double operator *(const point &b)const { 28 return x*b.x + y*b.y; 29 } 30 double operator ^(const point &b)const { //叉乘 31 return x*b.y - y*b.x; 32 } 33 bool operator <(point b)const { 34 return sgn(x - b.x) == 0 ? sgn(y - b.y)<0 : x<b.x; 35 } 36 //返回pa,pb的夹角,该点看a,b的夹角,弧度制 37 //弧度=度×π/180° 38 //度=弧度×180°/π 39 double rad(point a, point b) { 40 point p = *this; 41 return fabs(atan2(fabs((a - p) ^ (b - p)), (a - p)*(b - p))); 42 } 43 }point; 44 point p[maxn]; 45 int n = 0, res[maxn]; 46 int top;//top模拟栈顶 47 bool multi(point p1, point p2, point p0) { //判断p1p0和p2p0的关系,<0,p1p0在p2p0的逆时针方向,>0,p1p0在p2p0的顺时针方向 48 return (p1.x - p0.x)*(p2.y - p0.y) >= (p2.x - p0.x)*(p1.y - p0.y); 49 } 50 double Graham() { 51 int i, len;//top模拟栈顶 52 sort(p, p + n); 53 top = 1; 54 //少于3个点也就没有办法形成凸包 55 if (n == 0)return 0; res[0] = 0; 56 if (n == 1)return 0; res[1] = 1; 57 if (n == 2)return 0; res[2] = 2; 58 for (i = 2; i < n; i++) { 59 while (top&&multi(p[i], p[res[top]], p[res[top - 1]])) //如果当前这个点和栈顶两个点构成折线右拐了,就回溯到上一个点 60 top--; //弹出栈顶 61 res[++top] = i; //否则将这个点入栈 62 } 63 len = top; 64 res[++top] = n - 2; 65 for (i = n - 3; i >= 0; i--) { 66 while (top != len&&multi(p[i], p[res[top]], p[res[top - 1]])) 67 top--; 68 res[++top] = i; 69 } 70 double ans =0x3f3f3f; 71 res[top] = res[0],res[top + 1] = res[1]; 72 for (int i = 1; i <= top; i++) { 73 ans = min(ans, p[res[i]].rad(p[res[i + 1]], p[res[i - 1]])); 74 } 75 return ans / pi * 180; 76 } 77 inline int read() 78 { 79 int x = 0, f = 1; char ch = getchar(); 80 while (ch<‘0‘ || ch>‘9‘) { if (ch == ‘-‘)f = -1; ch = getchar(); } 81 while (ch >= ‘0‘&&ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); } 82 return x*f; 83 } 84 int main(void) { 85 int t; 86 t = read(); 87 for (int cnt = 1; cnt <= t; cnt++) { 88 cin >> n; 89 for (int i = 0; i < n; i++) { 90 p[i].x = read(); 91 p[i].y = read(); 92 } 93 printf("Case %d: ", cnt); 94 printf("%.7lf\n", Graham()); 95 } 96 return 0; 97 }
LightOJ 1203--Guarding Bananas(二维凸包+内角计算)
标签:als bool splay fast 折线 can link any mem
原文地址:https://www.cnblogs.com/FlyerBird/p/9557531.html