Gym 101673B Craters(凸包)
阿新 • • 發佈:2018-11-17
題目連結:傳送門
題意:給你n個圓的圓心座標和半徑,讓你求它們的外圍,且外圍與圓弧之間的距離要大於等於10.
思路:很明顯的一個凸包,所以我們將每個圓的圓弧上的點記錄下來(等分成5000份),然後進行凸包即可。
(好像精度有點差距,但奇妙的過了!)
附上程式碼:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<deque> #include<map> #include<queue> using namespace std; typedef long long ll; const double PI = acos(-1.0); const double eps = 1e-6; const int INF = 1000000000; const int MAXN = 1000100; struct point { double x, y; }; point list[MAXN]; int stack[MAXN], top; double cross(point p0, point p1, point p2) { return (p1.x - p0.x)*(p2.y - p0.y) - (p1.y - p0.y)*(p2.x - p0.x); } double dis(point p1, point p2) { return sqrt((double)(p2.x - p1.x)*(p2.x - p1.x) + (p2.y - p1.y)*(p2.y - p1.y)); } bool cmp(point p1, point p2) { double tmp = cross(list[0], p1, p2); if (tmp>0) return true; else if (tmp == 0 && dis(list[0], p1)<dis(list[0], p2)) return true; else return false; } void init(int n) { int i, k; point p0; p0.x = list[0].x; p0.y = list[0].y; k = 0; for (i = 1; i<n; i++) { if ((p0.y>list[i].y) || ((p0.y == list[i].y) && (p0.x>list[i].x))) { p0.x = list[i].x; p0.y = list[i].y; k = i; } } list[k] = list[0]; list[0] = p0; sort(list+1, list + n, cmp); } void graham(int n) { int i; if (n == 1) { top = 0; stack[0] = 0; } if (n == 2) { top = 1; stack[0] = 0; stack[1] = 1; } if (n>2) { for (i = 0; i <= 1; i++) stack[i] = i; top = 1; for (i = 2; i<n; i++) { while (top>0 && cross(list[stack[top - 1]], list[stack[top]], list[i]) <= 0) top--; top++; stack[top] = i; } } } int main(void) { int n; int summ = 0; scanf("%d", &n); double gg = PI/2500; for (int i = 0; i < n; i++) { double x, y,r; scanf("%lf%lf%lf", &x, &y,&r); r += 10; for (int j = 1; j <= 5000; j++) { list[summ].x = x + r*cos(gg*j); list[summ].y = y + r*sin(gg*j); summ++; } } init(summ); graham(summ); double ans = 0; for (int i = 0; i <= top; i++) { ans += dis(list[stack[i+1]], list[stack[i]]); } printf("%.10lf\n", ans); return 0; }