Problem D: Cutting tabletops
![](http://uva.onlinejudge.org/external/104/p10406a.jpg)
![](http://uva.onlinejudge.org/external/104/p10406b.jpg)
Input consists of a number of cases each presented on a separate line. Each line consists of a sequence of numbers. The first number is d the width of the strip of wood to be cut off of each edge of the tabletop in centimeters. The next number n is an integer giving the number of vertices of the polygon. The next npairs of numbers present xi and yi coordinates of polygon vertices for 1 <= i <= n given in clockwise order. A line containing only two zeroes terminate the input.
d is much smaller than any of the sides of the polygon. The beavers cut the edges one after another and after each cut the number of vertices of the tabletop is the same.
For each line of input produce one line of output containing one number to three decimal digits in the fraction giving the area of the tabletop after cutting.
Sample input
2 4 0 0 0 5 5 5 5 0 1 3 0 0 0 5 5 0 1 3 0 0 3 5.1961524 6 0 3 4 0 -10 -10 0 0 10 10 0 0 0
Output for sample input
1.000 1.257 2.785 66.294
角度x==角度y,证明很简单,略,然后就可以算出a了。
#include <iostream> #include <cstdio> #include <vector> #include <cmath> using namespace std; struct point{ double x , y; point(double a = 0.0 ,double b = 0.0){ x = a , y = b; } }; struct line{ point p1 , p2; line(point t1 , point t2){ p1 = t1 , p2 = t2; } }; vector<point> P; vector<line> L; int n; double ans ,d; double get_area(point p1 , point p2 , point p3){ return abs((p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x))/2; } double get_len(point p1 , point p2){ return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); } double get_angle(point p1 , point p , point p2){ return acos(((p1.x-p.x)*(p2.x-p.x)+(p1.y-p.y)*(p2.y-p.y))/(get_len(p1 , p)*get_len(p2 , p))); } void initial(){ P.clear(); L.clear(); ans = 0; } void readcase(){ double x , y; for(int i = 0; i < n; i++){ cin >> x >> y; P.push_back(point(x , y)); } for(int i = 0; i < n; i++){ L.push_back(line(P[i] , P[(i+1)%n])); } } void computing(){ for(int i = 1; i < n-1; i++){ ans += get_area(P[0] , P[i] , P[i+1]); } double len = 0; for(int i = 0; i < n; i++){ double angle = get_angle(L[i].p1 , L[i].p2 , L[(i+1)%n].p2); ans -= d*d/tan(angle/2); len += get_len(L[i].p1 , L[i].p2); len -= 2*d/tan(angle/2); } ans -= len*d; printf("%.3lf\n" , ans); } int main(){ while(cin >> d >> n && (n != 0 || d != 0)){ initial(); readcase(); computing(); } return 0; }