POJ 2540 Hotter Colder 半平面交 求可行域面积
题意:
有一个二维(0,0)到(10,10)的区域,一个人从(0,0)开始一次拜访区域内的点,去找一样东西(就在这个区域内),每次他到达一个新的点后,都会有一句话,来告诉你是离那个东西更近了(Hotter),还是更远了(Colder),或者距离不变(Same),然后让你算出,这时那个东西可能处在的位置的区域的面积
注意点:
1. 这题主要搞清楚半平面要取到的区域,还有中垂线自己YY。
小知识: 与直线ax+by+c=0垂直的直线方程为bx-ay+d = 0, 根据这个不用考虑斜率为0或不存在的问题,很方便。
2. same以后的值都为0;
其它 模板。
模板1:
View Code
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; #define eps 1e-8 #define inf 1<<29 struct point { double x, y; point(){} point(double xx, double yy): x(xx), y(yy) {} }p[110], tp[110], cur, pre; int n, m; void getline(point p1, point p2, double &a, double &b, double &c) //获得中垂线 { point p3 = point( (p1.x + p2.x)/2, (p1.y + p2.y)/2 ); a = p1.x - p2.x; b = p1.y - p2.y; c = - a * p3.x - b * p3.y; } point intersect(point p1, point p2, double a, double b, double c) { double u = fabs(a * p1.x + b * p1.y + c); double v = fabs(a * p2.x + b * p2.y + c); point ans; ans.x = (v * p1.x + u * p2.x) / (u + v); ans.y = (v * p1.y + u * p2.y) / (u + v); return ans; } void cut(double a, double b, double c)//切割 { int i, tm = 0; for(i = 1; i <= m; i++) { if(a * p[i].x + b * p[i].y + c > eps) tp[++tm] = p[i]; else { if( a * p[i-1].x + b * p[i-1].y + c > eps) tp[++tm] = intersect(p[i-1], p[i], a, b, c); if( a * p[i+1].x + b * p[i+1].y + c > eps) tp[++tm] = intersect(p[i], p[i+1], a, b, c); } } for(i = 1; i <= tm; i++) p[i] = tp[i]; p[0] = p[tm]; p[tm+1] = p[1]; m = tm; } double cal(int n, point *p) //多边形面积 { int i; double s = 0; p[n+1] = p[1]; for(i = 1; i <= n; i++) s += p[i].x * p[i+1].y - p[i].y *p[i+1].x; return fabs(s) / 2; } char str[11]; int main() { //freopen("int.txt", "r", stdin); int i, j; bool flag = 0; double a, b, c; pre = point(0, 0); m = n = 4; p[1] = point(0, 0); p[2] = point(0, 10); p[3] = point(10, 10); p[4] = point(10, 0); p[5] = p[1]; p[0] = p[4]; while( ~scanf("%lf%lf%s", &cur.x, &cur.y, str) ) { getline(pre, cur, a, b, c); if(str[0] == 'C') { if(a * pre.x + b * pre.y + c < -eps) { a = -a; b = -b; c = -c; } } else if(str[0] == 'H') { if(a * cur.x + b * cur.y + c < -eps) { a = -a; b = -b; c = -c; } } else flag = 1; //注意same以后,每次答案都为0; if(flag) { puts("0.00"); continue; } cut(a, b, c); printf("%.2f\n", cal(m, p)); pre = cur; } return 0; }
模板2:
View Code
#include<stdio.h> #include<string.h> #include<math.h> #include<vector> #include<algorithm> using namespace std; #define eps 1e-8 struct point { double x, y; bool mark; point(){} point(double xx, double yy): x(xx), y(yy), mark(1) {} }cur, pre; vector<point> p; point mid(point p1, point p2) { point ans; ans.x = (p1.x + p2.x) / 2; ans.y = (p1.y + p2.y) / 2; return ans; } void getline(point p1, point p2, double &a, double &b, double &c) { point p3 = mid(p1, p2); a = p1.x - p2.x; b = p1.y - p2.y; c = -a * p3.x - b * p3.y; } point intersect( point p1, point p2, double a, double b, double c) { double u = fabs( a * p1.x + b * p1.y + c ); double v = fabs( a * p2.x + b * p2.y + c ); point ans; ans.x = (v * p1.x + u * p2.x) / (u + v); ans.y = (v * p1.y + u * p2.y) / (u + v); return ans; } void cut(double a, double b, double c) { int i; point tp; for(i = 0; i < p.size(); i++) { if(a * p[i].x + b * p[i].y + c > eps) p[i].mark= 1; else p[i].mark = 0; } p.push_back( p[0] ); for(i = 0; i < p.size() - 1; i++) if( p[i].mark^p[i+1].mark == 1) { tp = intersect(p[i], p[i+1], a, b, c); p.insert(p.begin()+i+1, tp); i++; } p.pop_back(); for(i = 0; i < p.size(); i++) if(p[i].mark == 0) p.erase(p.begin()+i), i--; } double cal() { p.push_back(p[0]); double s = 0; int i; for(i = 0; i < p.size() - 1; i++) s += p[i].x *p[i+1].y - p[i].y * p[i+1].x; p.pop_back(); return fabs(s)/2; } char str[11]; int main() { //freopen("int.txt", "r", stdin); int i, j; bool flag = 0; double a, b, c; p.clear(); p.push_back( point (0, 0)); p.push_back( point (0, 10)); p.push_back( point (10, 10)); p.push_back( point (10, 0)); pre = point(0, 0); while( scanf("%lf%lf%s", &cur.x, &cur.y, str) != EOF ) { getline(pre, cur, a, b, c); if(str[0] == 'C') { if(a * pre.x + b * pre.y + c < -eps) { a = -a; b = -b; c = -c;} } else if(str[0] == 'H') { if(a * cur.x + b * cur.y + c < -eps) { a = -a; b = -b; c = -c;} } else flag = 1; if(flag) { printf("0.00\n"); continue; } cut(a, b, c); printf("%.2f\n", cal()); pre = cur; } return 0; }


浙公网安备 33010602011771号