zoj 1886 || poj 2540 || UVA 10084 Hotter Colder
2011-07-21 20:43
399 查看
这题应该是经典题了吧,要不三个OJ都有。。。
0 0 到 10,10区域中有个东西,你在0,0点,如果你走到某个点然后会告诉你离那个东西是近了还是远了。近了就是hotter 远了是colder,如果距离不变的话,就是same。
这样的话,等于每次走一次就确定一个半平面区域,也就是从这个点到另一个点的中垂线然后分割成的半平面,自己可以画图。根据hotter或者colder确定是半平面的方向。
N*LOGN的模板,不过需要注意几点。
1)半平面的方向,我是默认半平面的方向为左侧区域,然后用线段表示的时候注意下
2)如果面积为0 那么以后都输出0。这点没判断,然后zoj过不去 = =。。。。
3)出现same就为0.0。开始判断如果出现重复点就不判断,后来这个判断删了也没事,估计数据没有这种。
O N^2的
0 0 到 10,10区域中有个东西,你在0,0点,如果你走到某个点然后会告诉你离那个东西是近了还是远了。近了就是hotter 远了是colder,如果距离不变的话,就是same。
这样的话,等于每次走一次就确定一个半平面区域,也就是从这个点到另一个点的中垂线然后分割成的半平面,自己可以画图。根据hotter或者colder确定是半平面的方向。
N*LOGN的模板,不过需要注意几点。
1)半平面的方向,我是默认半平面的方向为左侧区域,然后用线段表示的时候注意下
2)如果面积为0 那么以后都输出0。这点没判断,然后zoj过不去 = =。。。。
3)出现same就为0.0。开始判断如果出现重复点就不判断,后来这个判断删了也没事,估计数据没有这种。
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <stack> #include <climits> using namespace std; const int MAX = 55; struct point {double x,y;}; struct line { point a,b; double ang;}; line ln[MAX],deq[MAX],ltmp[MAX]; point s[MAX]; const double eps = 1e-6; bool dy(double x,double y) { return x > y + eps;} // x > y bool xy(double x,double y) { return x < y - eps;} // x < y bool dyd(double x,double y) { return x > y - eps;} // x >= y bool xyd(double x,double y) { return x < y + eps;} // x <= y bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 { return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y); } void makeline(double x1,double y1,double x2,double y2,line &l) { l.a.x = x1; l.a.y = y1; l.b.x = x2; l.b.y = y2; l.ang = atan2(y1 - y2,x1 - x2); } point foot_line(point a,point l1,point l2) //ac在l1l2的逆时针方向 { point c; c.x = a.x - l2.y + l1.y; c.y = a.y + l2.x - l1.x; return c; } bool cmphp(line a,line b) { if( dd(a.ang,b.ang) ) return xy(crossProduct(b.a,b.b,a.a),0.0); return xy(a.ang,b.ang); } bool equalcmp(line a,line b) { return dd(a.ang,b.ang); } bool parallel(line u,line v) { return dd( (u.a.x - u.b.x)*(v.a.y - v.b.y) - (v.a.x - v.b.x)*(u.a.y - u.b.y) , 0.0 ); } bool equalp(point a,point b) { return dd(a.x,b.x) && dd(a.y,b.y); } double area_polygon(point p[],int n) { double s = 0.0; for(int i=0; i<n; i++) s += p[(i+1)%n].y * p[i].x - p[(i+1)%n].x * p[i].y; return fabs(s)/2.0; } point l2l_inst_p(line l1,line l2) { point ans = l1.a; double t = ((l1.a.x - l2.a.x)*(l2.a.y - l2.b.y) - (l1.a.y - l2.a.y)*(l2.a.x - l2.b.x))/ ((l1.a.x - l1.b.x)*(l2.a.y - l2.b.y) - (l1.a.y - l1.b.y)*(l2.a.x - l2.b.x)); ans.x += (l1.b.x - l1.a.x)*t; ans.y += (l1.b.y - l1.a.y)*t; return ans; } void inst_hp_nlogn(line *ln,int n,point *s,int &len) { len = 0; sort(ln,ln+n,cmphp); n = unique(ln,ln+n,equalcmp) - ln; int bot = 0,top = 1; deq[0] = ln[0]; deq[1] = ln[1]; for(int i=2; i<n; i++) { if( parallel(deq[top],deq[top-1]) || parallel(deq[bot],deq[bot+1]) ) return ; while( bot < top && dy(crossProduct(ln[i].a,ln[i].b, l2l_inst_p(deq[top],deq[top-1])),0.0) ) top--; while( bot < top && dy(crossProduct(ln[i].a,ln[i].b, l2l_inst_p(deq[bot],deq[bot+1])),0.0) ) bot++; deq[++top] = ln[i]; } while( bot < top && dy(crossProduct(deq[bot].a,deq[bot].b, l2l_inst_p(deq[top],deq[top-1])),0.0) ) top--; while( bot < top && dy(crossProduct(deq[top].a,deq[top].b, l2l_inst_p(deq[bot],deq[bot+1])),0.0) ) bot++; if( top <= bot + 1 ) return ; for(int i=bot; i<top; i++) s[len++] = l2l_inst_p(deq[i],deq[i+1]); if( bot < top + 1 ) s[len++] = l2l_inst_p(deq[bot],deq[top]); len = unique(s,s+len,equalp) - s; } int main() { double x,y; char str[100]; point a,b; a.x = a.y = 0.0 ; int cnt = 0; double area = 1e20; makeline(0,0,10,0,ln[cnt++]); makeline(10,0,10,10,ln[cnt++]); makeline(10,10,0,10,ln[cnt++]); makeline(0,10,0,0,ln[cnt++]); while( ~scanf("%lf%lf%s",&b.x,&b.y,str) ) { if( strcmp(str,"Same") == 0 ) area = 0.0; point c; c.x = (a.x + b.x)/2.0; c.y = (a.y + b.y)/2.0; point d; if( strcmp(str,"Colder") == 0 ) { d = foot_line(c,a,b); makeline(c.x,c.y,d.x,d.y,ln[cnt++]); } if( strcmp(str,"Hotter") == 0 ) { d = foot_line(c,a,b); makeline(d.x,d.y,c.x,c.y,ln[cnt++]); } a = b; if( area == 0.0 ) { printf("0.00\n"); continue; } int len = 0; memcpy(ltmp,ln,sizeof(ln)); inst_hp_nlogn(ltmp,cnt,s,len); area = area_polygon(s,len); if( len < 3 ) { printf("0.00\n"); continue; } printf("%.2lf\n",area); } return 0; }
O N^2的
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <stack> #include <climits> using namespace std; const int MAX = 55; struct point {double x,y;}; point p[MAX]; const double eps = 1e-6; bool dy(double x,double y) { return x > y + eps;} // x > y bool xy(double x,double y) { return x < y - eps;} // x < y bool dyd(double x,double y) { return x > y - eps;} // x >= y bool xyd(double x,double y) { return x < y + eps;} // x <= y bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 { return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y); } point foot_line(point a,point l1,point l2) //ac在l1l2的逆时针方向 { point c; c.x = a.x - l2.y + l1.y; c.y = a.y + l2.x - l1.x; return c; } double area_polygon(point p[],int n) { double s = 0.0; for(int i=0; i<n; i++) s += p[(i+1)%n].y * p[i].x - p[(i+1)%n].x * p[i].y; return fabs(s)/2.0; } point l2l_inst_p(point u1,point u2,point v1,point v2) { point ans = u1; double t = ((u1.x - v1.x)*(v1.y - v2.y) - (u1.y - v1.y)*(v1.x - v2.x))/ ((u1.x - u2.x)*(v1.y - v2.y) - (u1.y - u2.y)*(v1.x - v2.x)); ans.x += (u2.x - u1.x)*t; ans.y += (u2.y - u1.y)*t; return ans; } void makepoint(double x,double y,int &n) { p .x = x; p[n++].y = y; } void cut_hp(point a,point b,point *s,int &len) { int tc = 0; point tp[MAX]; for(int i=0; i<=len; i++) tp[i] = s[i]; for(int i=0; i<=len; i++) { if( xyd(crossProduct(a,b,tp[i]),0.0) ) s[tc++] = tp[i]; if( xy(crossProduct(a,b,tp[i])* crossProduct(a,b,tp[i+1]),0.0) ) s[tc++] = l2l_inst_p(a,b,tp[i],tp[i+1]); } s[tc] = s[0]; len = tc; } int main() { double x,y; char str[100]; point a,b,c,d; a.x = a.y = 0.0 ; double area = 1e20; int len = 0; makepoint(0,0,len); makepoint(10,0,len); makepoint(10,10,len); makepoint(0,10,len); p[4] = p[0]; while( ~scanf("%lf%lf%s",&b.x,&b.y,str) ) { if( strcmp(str,"Same") == 0 ) area = 0.0; c.x = (a.x + b.x)/2.0; c.y = (a.y + b.y)/2.0; if( strcmp(str,"Colder") == 0 ) d = foot_line(c,a,b); if( strcmp(str,"Hotter") == 0 ) { d = foot_line(c,a,b); swap(c,d); } a = b; if( area == 0.0 ) { printf("0.00\n"); continue; } cut_hp(c,d,p,len); area = area_polygon(p,len); if( len < 3 ) { printf("0.00\n"); continue; } printf("%.2lf\n",area); } return 0; }
相关文章推荐
- POJ 2540 ZOJ 1886 Hotter Colder 半平面交
- poj 2540 && uva 10084 Hotter Colder(半平面交)
- uva 10129 poj 1386 hdu 1116 zoj 2016 play on words
- POJ 2540 Hotter Colder(半平面交)
- POJ 2540 Hotter Colder(半平面交)
- UVA713 UVALive5539 POJ1504 ZOJ2001 Adding Reversed Numbers
- uva 10084 Hotter Colder
- POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat 二分)
- uva 10084 Hotter Colder
- (beginer) 半平面交 UVA 10084 - Hotter Colder
- UVALive2953 POJ1775 ZOJ2358 Sum of Factorials【打表+暴力+水题】
- UVa 439/HDU 1372/POJ 2243/ZOJ 1091 Knight Moves(BFS&纯数学方法)
- POJ1003 UVALive2294 HDU1056 ZOJ1045 Hangover【数学计算+水题】
- uva 10084 - Hotter Colder(多边形切割)
- POJ 2540 Hotter Colder 半平面交 求可行域面积
- POJ2608 ZOJ1858 UVA10260 Soundex【编码】
- UVA - 10084 Hotter Colder(半平面交)
- poj 2540 Hotter Colder 切割多边形
- POJ2562 UVA10035 ZOJ1874 Primary Arithmetic【进制+进位】
- POJ1316 ZOJ1180 UVA640