题解
- 如果比之前更远,那么在两点的中垂线靠近之前的那边,反之另一边。
- 我们可以找出a和b的终点,在把确定向量ab,根据情况旋转90或270。
- 如果出现same那就不再计算 了。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
const double eps = 1e-10;
double const PI = acos(-1);
double const inf = 1e10;
int const N = 100 + 10;
int n;
int dcmp(double x){ //判断符号
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
typedef struct Point{ //点和向量
double x,y;
Point(){};
Point(double x,double y):x(x),y(y){};
Point operator + (const Point& e)const{ //加
return Point(x + e.x,y + e.y);
}
Point operator - (const Point& e)const{ //减
return Point(x - e.x,y - e.y);
}
Point operator * (const double e)const{ //乘
return Point(x * e,y * e);
}
Point operator / (const double e)const{ //除
return Point(x / e,y / e);
}
bool operator == (const Point &e)const{ //相等
return !dcmp(x - e.x) && !dcmp(y - e.y);
}
bool operator < (const Point& e)const{ //比较
return x < e.x || x == e.x && y < e.y;
}
}Vector;
Point a[N],p[N],t[N];
double Dot(Vector a,Vector b){
return a.x * b.x + a.y * b.y;
}
double Cross(Vector a,Vector b){
return a.x * b.y - a.y * b.x;
}
struct Line
{
Point a,b;
double ang;
void getang(){ ang = atan2(b.y - a.y,b.x - a.x);}
bool operator == (const Line& e)const{
return !dcmp(ang - e.ang);
}
bool operator < (const Line& e)const{
return ang < e.ang || !dcmp(ang - e.ang) && dcmp(Cross(b - a,e.b - a)) < 0;
}
}s[N],q[N];
Point intersection(Point p,Vector v,Point q,Vector w){ //两直线(p+tv)和(q+tw)求交点
Vector u = p - q;
double t = Cross(w,u) / Cross(v,w);
return p + Point(v.x * t,v.y * t);
}
bool onright(Point a,Point b,Point p){
return dcmp(Cross(b - a,p - a)) < 0;
}
int halfplaneintersection(){
for(int i=0;i<n;i++) s[i].getang();
sort(s,s+n);
int l,r;
q[l = r = 0] = s[0];
for(int i=1;i<n;i++){
if(s[i] == s[i-1]) continue;
while(l < r && onright(s[i].a,s[i].b,t[r-1])) r--;
while(l < r && onright(s[i].a,s[i].b,t[l])) l++;
q[++r] = s[i];
if(l < r) t[r-1] = intersection(q[r].a,q[r].a - q[r].b,q[r-1].a,q[r-1].a - q[r-1].b);
}
while(l < r && onright(q[l].a,q[l].b,t[r-1])) r--;
t[r] = intersection(q[l].a,q[l].a-q[l].b,q[r].a,q[r].a-q[r].b);
if(r - l <= 1) return 0; //不存在
int m = 0;
for(int i=l;i<=r;i++) p[m++] = t[i];
return m;
}
Vector Rotate(Vector A,double rad){
return Vector(A.x * cos(rad) - A.y * sin(rad),A.x * sin(rad) + A.y * cos(rad));
}
double Length(Vector A){
return sqrt(Dot(A,A));
}
Vector Normal(Vector A){
double len = Length(A);
return Vector(A.x / len,A.y / len);
}
double getarea(int n,Point *p){
double ans = 0;
for(int i=1;i<n-1;i++)
ans += Cross(p[i] - p[0],p[i+1] - p[0]);
return fabs(ans) / 2;
}
int main(){
double x,y;
char str[N];
Point last = Point(0,0),now,mid;
double ans = inf;
s[n++] = (Line){Point(0,0),Point(0,0) + Vector(1,0)};
s[n++] = (Line){Point(10,0),Point(10,0) + Vector(0,1)};
s[n++] = (Line){Point(10,10),Point(10,10) + Vector(-1,0)};
s[n++] = (Line){Point(0,10),Point(0,10) + Vector(0,-1)};
while(~scanf("%lf%lf %s",&x,&y,str)){
if(!strcmp(str,"Same") || !dcmp(ans)){
ans = 0;
printf("%.2f\n",ans);
continue;
}
now = Point(x,y);
mid = (last + now) / 2;
Vector v = now - last;
Vector v1;
if(!strcmp(str,"Colder")) v = Rotate(v,PI/2);
else v = Rotate(v,3*PI/2);
s[n++] = (Line){mid,mid + v};
int m = halfplaneintersection();
double ans = getarea(m,p);
printf("%.2f\n",ans);
last = now;
}
return 0;
}