POJ 2540 Hotter Colder --半平面交
题意: 一个(0,0)到(10,10)的矩形,目标点不定,从(0,0)开始走,如果走到新一点是"Hotter",那么意思是离目标点近了,如果是"Colder“,那么就是远了,"Same"是相同。要你推测目标点的可能位置的面积。
解法:半平面交水题。从一个点到另一个点远了,说明目标点在两点之间连线的中垂线的离源点较近的一侧,即我们每次都可以得到一条直线来切割平面,要么切割左侧,要么切割右侧,要么都切,再求一个半平面交就可以得出可能面积了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define pi acos(-1.0)
#define eps 1e-8
using namespace std; struct Point{
double x,y;
Point(double x=, double y=):x(x),y(y) {}
void input() { scanf("%lf%lf",&x,&y); }
};
typedef Point Vector;
struct Line{
Point p;
Vector v;
double ang;
Line(){}
Line(Point p, Vector v):p(p),v(v) { ang = atan2(v.y,v.x); }
Point point(double t) { return Point(p.x + t*v.x, p.y + t*v.y); }
bool operator < (const Line &L)const { return ang < L.ang; }
};
int dcmp(double x) {
if(x < -eps) return -;
if(x > eps) return ;
return ;
}
template <class T> T sqr(T x) { return x * x;}
Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }
bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }
bool operator == (const Point& a, const Point& b) { return dcmp(a.x-b.x) == && dcmp(a.y-b.y) == ; }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
Vector VectorUnit(Vector x){ return x / Length(x);}
Vector Normal(Vector x) { return Point(-x.y, x.x) / Length(x);}
double angle(Vector v) { return atan2(v.y, v.x); } Point GetLineIntersection(Line A, Line B) {
Vector u = A.p - B.p;
double t = Cross(B.v, u) / Cross(A.v, B.v);
return A.p + A.v*t;
}
double DisP(Point A,Point B) {
return Length(B-A);
}
double CalcConvexArea(Point* p,int n) { //凸包面积
double area = 0.0;
for(int i=;i<n-;i++)
area += Cross(p[i]-p[],p[i+]-p[]);
return fabs(area*0.5);
}
bool OnLeft(Line L, Point p) { return dcmp(Cross(L.v,p-L.p)) > ; }
bool CmpPolarLine(Line a,Line b) { //直线极角排序
return angle(a.v) < angle(b.v);
}
int HalfPlaneIntersection(Line* L, int n, Point* poly) { //半平面交点存入poly
sort(L,L+n,CmpPolarLine);
int first,last;
Point *p = new Point[n];
Line *q = new Line[n];
q[first=last=] = L[];
for(int i=;i<n;i++) {
while(first < last && !OnLeft(L[i],p[last-])) last--;
while(first < last && !OnLeft(L[i],p[first])) first++;
q[++last] = L[i];
if(dcmp(Cross(q[last].v, q[last-].v)) == ) {
last--;
if(OnLeft(q[last], L[i].p)) q[last] = L[i];
}
if(first < last) p[last-] = GetLineIntersection(q[last-],q[last]);
}
while(first < last && !OnLeft(q[first],p[last-])) last--;
if(last-first <= ) return ; //点或线或无界平面,返回0
p[last] = GetLineIntersection(q[last],q[first]);
int m = ;
for(int i=first;i<=last;i++) poly[m++] = p[i];
delete p; delete q;
return m;
} Line L[],TL[];
Point poly[]; int main()
{
int i,j,tot = -;
Point n,p;
char ss[];
p.x = p.y = 0.0;
TL[++tot] = Line(Point(,),Vector(,));
TL[++tot] = Line(Point(,),Vector(,));
TL[++tot] = Line(Point(,),Vector(-,));
TL[++tot] = Line(Point(,),Vector(,-));
while(scanf("%lf%lf%s",&n.x,&n.y,ss)!=EOF)
{
if(ss[] == 'H')
TL[++tot] = Line(Point((n.x+p.x)/2.0,(n.y+p.y)/2.0),Vector(Normal(p-n)));
else if(ss[] == 'C')
TL[++tot] = Line(Point((n.x+p.x)/2.0,(n.y+p.y)/2.0),Vector(Normal(n-p)));
else {
TL[++tot] = Line(Point((n.x+p.x)/2.0,(n.y+p.y)/2.0),Vector(Normal(p-n)));
TL[++tot] = Line(Point((n.x+p.x)/2.0,(n.y+p.y)/2.0),Vector(Normal(n-p)));
}
p = n;
for(i=;i<=tot;i++) L[i] = TL[i];
int m = HalfPlaneIntersection(L,tot+,poly);
if(!m) puts("0.00");
else printf("%.2f\n",CalcConvexArea(poly,m));
}
return ;
}
POJ 2540 Hotter Colder --半平面交的更多相关文章
- poj 2540 Hotter Colder 切割多边形
/* poj 2540 Hotter Colder 切割多边形 用两点的中垂线切割多边形,根据冷热来判断要哪一半 然后输出面积 */ #include <stdio.h> #include ...
- POJ 2540 Hotter Colder(半平面交)
Description The children's game Hotter Colder is played as follows. Player A leaves the room while p ...
- POJ 2540 Hotter Colder
http://poj.org/problem?id=2540 题意:给你每次行走的路径,而且告诉你每次离一个点光源是远了还是近了,要求每次光源可能存在的位置的面积. 思路:如果出现"same ...
- 2018.07.03 POJ 1279Art Gallery(半平面交)
Art Gallery Time Limit: 1000MS Memory Limit: 10000K Description The art galleries of the new and ver ...
- POJ 3335 Rotating Scoreboard 半平面交求核
LINK 题意:给出一个多边形,求是否存在核. 思路:比较裸的题,要注意的是求系数和交点时的x和y坐标不要搞混...判断核的顶点数是否大于1就行了 /** @Date : 2017-07-20 19: ...
- POJ 1474 Video Surveillance 半平面交/多边形核是否存在
http://poj.org/problem?id=1474 解法同POJ 1279 A一送一 缺点是还是O(n^2) ...nlogn的过几天补上... /********************* ...
- POJ 1279 Art Gallery 半平面交/多边形求核
http://poj.org/problem?id=1279 顺时针给你一个多边形...求能看到所有点的面积...用半平面对所有边取交即可,模版题 这里的半平面交是O(n^2)的算法...比较逗比.. ...
- POJ 1279 Art Gallery 半平面交求多边形核
第一道半平面交,只会写N^2. 将每条边化作一个不等式,ax+by+c>0,所以要固定顺序,方便求解. 半平面交其实就是对一系列的不等式组进行求解可行解. 如果某点在直线右侧,说明那个点在区域内 ...
- POJ 1755 Triathlon (半平面交)
Triathlon Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4733 Accepted: 1166 Descrip ...
随机推荐
- JavaScript基础系列(变量与类型)
以下内容将JavaScript简称为JS 打开本文时不管你是零基础的初学者还是其他语言的老兵,我都想说程序语言的基础支撑起了整个网络世界,不把这些基础学透之后稍复杂的内容会让你寸步难行. 现在先给编程 ...
- 微信网页授权(OAuth2.0) PHP 源码简单实现
提要: 1. 建议对OAuth2.0协议做一个学习. 2. 微信官方文档和微信官网工具要得到充分利用. 比较简单,直接帖源代码了.其中“xxxxxxxxxx”部分,是需要依据自己环境做替换的 /** ...
- Java虚拟机JVM学习07 类的卸载机制
Java虚拟机JVM学习07 类的卸载机制 类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就 ...
- Android Contextual Menus之一:floating context menu
Android Contextual Menus之一:floating context menu 上下文菜单 上下文相关的菜单(contextual menu)用来提供影响UI中特定item或者con ...
- Android 获取系统的联系人
本文主要介绍android中怎样获取系统的联系人数据 首先打开模拟器 点击联系人图标按钮 说明系统联系人数据库是空的,打开File explorer,找到data/data下面的文件夹: 将conta ...
- Java核心:类加载和JVM内存的分配
类的加载: 指的是将class文件的二进制数据读入到运行时数据区(JVM在内存中划分的) 中,并在方法区内创建一个class对象. 类加载器: 负责加载编译后的class文件(字节码文件)到JVM(J ...
- OC中面向对象2
一. 定义OC的类和创建OC的对象 接下来就在OC中模拟现实生活中的情况,创建一辆车出来.首先要有一个车子类,然后再利用车子类创建车子对象 要描述OC中的类稍微麻烦一点,分2大步骤:类的声明.类的实现 ...
- Android按键事件处理流程 -- KeyEvent
刚接触Android开发的时候,对touch.key事件的处理总是一知半解,一会是Activity里的方法,一会是各种View 中的,自己始终不清楚到底哪个在先哪个在后,总之对整个处理流程没能很好的把 ...
- 设计模式 之 装饰者(Decorator)模式
装饰者模式(Decorator):动态地为一个对象添加一些额外的职责,若要扩展一个对象的功能,装饰者提供了比继承更有弹性的替代方案. 结构图: 抽象构件类(Component):给出一个抽象的接口,用 ...
- javascript和web debug技术
在前端开发中,调试技术是必不可少的技能,本文将介绍五种前端开发必备的调试技术. Weinre移动调试 DOM 断点 debugger断点 native方法hook 远程映射本地调试 Weinre 在移 ...