Why so serious? --[NKU]schindlerlee

pku3334 二分+求多边形面积

 1 /*
 2  * SOUR:pku3334
 3  * ALGO:二分高度,求水平线和多边形的交点,求出多边形面积
 4  * DATE: 2010年 07月 07日 星期三 22:29:14 CST
 5  * */
 6 const int N = 1024;
 7 struct point_t {
 8     double x, y;
 9     point_t (){}
10     point_t (double a, double b){x = a, y = b;}
11 }P[N], Q[N];
12 int m, n, cp, cq;
13 double area;
14 
15 point_t operator + (point_t a, point_t b) { return point_t(a.x + b.x, a.y + b.y);}
16 point_t operator - (point_t a, point_t b) { return point_t(a.x - b.x, a.y - b.y);}
17 double SQR(double x ){ return x * x;}
18 double dist(point_t a) { return sqrt(SQR(a.x) + SQR(a.y));}
19 double dist(point_t a, point_t b) { return dist(a-b);}
20 double cross_mul(point_t a, point_t b) { return a.x * b.y - a.y * b.x;}
21 const double eps = 1e-10;
22 
23 double calcu(point_t p[], int n, int cusp, double h)
24 {
25   double ans = 0;
26   int i, j, k, beg = 0, end = n - 1;
27   if (h <= p[cusp].y) {
28       return 0;
29   }
30   for (i = 0;i < cusp;i ++) {
31       if (p[i].y >= h && h >= p[i+1].y) {
32           beg = i;break;
33       }
34   }
35   for (i = n - 2;i >= cusp;i--) {
36       if (p[i].y <= h && h <= p[i+1].y) {
37           end = i;break;
38       }
39   }
40 
41   point_t a = point_t(p[beg].x + (h - p[beg].y) * (p[beg+1].x - p[beg].x)
42                       / (p[beg+1].y - p[beg].y) , h);
43   point_t b = point_t(p[end].x + (h - p[end].y) * (p[end+1].x - p[end].x)
44                       / (p[end+1].y - p[end].y) , h);
45   ans += cross_mul(a, p[beg+1]) + cross_mul(p[end], b) + cross_mul(b, a);
46   for (i = beg + 1;i <= end - 1;i++) {
47       ans += cross_mul(p[i], p[i+1]);
48   }
49   return fabs(ans / 2.0);
50 }
51 
52 int main()
53 {
54   int testcase, i;
55   scanf("%d"&testcase);
56   while (testcase--) {
57       scanf("%lf"&area);
58       scanf("%d"&m); for (i = 0;i < m;i++) { scanf("%lf %lf"&P[i].x, &P[i].y); }
59       scanf("%d"&n); for (i = 0;i < n;i++) { scanf("%lf %lf"&Q[i].x, &Q[i].y); }
60       for (i = 1;i < m-1;i++) {
61           if (P[i-1].y >= P[i].y && P[i].y <= P[i+1].y) {
62               cp = i;
63           }
64       }
65       for (i = 1;i < n-1;i++) {
66           if (Q[i-1].y >= Q[i].y && Q[i].y <= Q[i+1].y) {
67               cq = i;
68           }
69       }
70       double L = min(P[cp].y , Q[cq].y),
71              R = min(min(P[0].y, P[m - 1].y) , min(Q[0].y, Q[n - 1].y)) ;
72       while (L + eps < R) {
73           double mid = (L + R) / 2.0;
74           double A = calcu(P, m, cp, mid) + calcu(Q, n, cq, mid);
75           //printf("h = %.3f, A = %.3f\n", mid, A);
76           if (A <= area) {
77               L = mid;
78           }else {
79               R = mid;
80           }
81       }
82       printf("%.3f\n", L);
83   }
84   return 0;
85 }
86 
87 
88 

posted on 2010-07-08 21:34 schindlerlee 阅读(1610) 评论(0)  编辑 收藏 引用 所属分类: 解题报告


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理