还没开始写题解我就已经内牛满面了,从晚饭搞到现在,WA得我都快哭了呢

题意:

在DotA中,你现在1V5,但是你的英雄有一个半径为r的眩晕技能,已知敌方五个英雄的坐标,问能否将该技能投放到一个合适的位置,使得对面所有敌人都被眩晕,这样你就有机会能够逃脱。

分析:

对于敌方一个英雄来说,如果技能的投放位置距离他不超过r则满足要求,那么如果要眩晕所有的敌人,可行区域就是以五人为中心的半径为r的圆的相交区域。

现在问题就转化为求五个半径相同的圆的相交部分的面积,如果只有一个点则输出该点。

在求交之前,我们可以先去除

我们将所交区域划分为一个凸多边形和周围若干个弓形。

弓形在两圆相交时便能求出,而且还能求出两圆的交点(注意两个交点p1,p2一定要按照逆时针的顺序,因为叉积有正负),也就是凸多边的顶点,其面积形直接用叉积来计算。

给两个传送门,认真学习一下吧:

http://www.cnblogs.com/oyking/archive/2013/11/14/3424517.html

对于枚举一个圆求与另外四个圆相交区域,是按照极角的区间求交集,详见:

http://hi.baidu.com/aekdycoin/item/7618bee9f473ed3e86d9ded6

五个圆是否交于一点还要另行判断

最后再感慨一下做计算几何说多了都是泪啊

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm> const int maxn = ;
const double eps = 1e-;
const double PI = acos(-1.0); int dcmp(double x)
{ return (x > eps) - (x < -eps); } struct Point
{
double x, y;
Point(double x=, double y=):x(x), y(y) {}
void read() { scanf("%lf%lf", &x, &y); }
};
typedef Point Vector;
Point operator + (const Vector& a, const Vector& b)
{ return Point(a.x+b.x, a.y+b.y); }
Point operator - (const Vector& a, const Vector& b)
{ return Point(a.x-b.x, a.y-b.y); }
Vector operator * (const Vector& a, double p)
{ return Point(a.x*p, a.y*p); }
Vector operator / (const Vector& a, double p)
{ return Point(a.x/p, a.y/p); }
bool operator == (const Point& a, const Point& b)
{ return dcmp(a.x-b.x) == && dcmp(a.y-b.y) == ; } double Dot(const Vector& a, const Vector& b)
{ return a.x*b.x + a.y*b.y; }
double Cross(const Vector& a, const Vector& b)
{ return a.x*b.y - a.y*b.x; }
double Length(const Vector& a)
{ return sqrt(Dot(a, a)); }
Vector unit(const Vector& a)
{ return a / Length(a); }
Vector Normal(const Vector& a)
{
double l = Length(a);
return Vector(-a.y/l, a.x/l);
}
double Angle(const Vector& a)
{ return atan2(a.y, a.x); } Point Rotate(const Point& p, double angle, const Point& o = Point(, ))
{
Vector t = p - o;
t = Vector(t.x*cos(angle)-t.y*sin(angle), t.x*sin(angle)+t.y*cos(angle));
return t + o;
} struct Region
{
double st, ed;
Region(double s=, double e=):st(s), ed(e) {}
}; struct Circle
{
Point c;
double r;
Circle() {}
Circle(Point c, double r):c(c), r(r) {} void read() { c.read(); scanf("%lf", &r); } double area() const { return PI * r * r; } bool contain(const Circle& rhs) const
{ return dcmp(Length(c-rhs.c) + rhs.r - r) <= ; } bool contain(const Point& p) const
{ return dcmp(Length(c-p) - r) <= ; } bool intersect(const Circle& rhs) const
{ return dcmp(Length(c-rhs.c) - r - rhs.r) < ; } bool tangency(const Circle& rhs) const
{ return dcmp(Length(c-rhs.c) - r - rhs.r) == ; } Point get_point(double ang) const
{ return Point(c.x + r * cos(ang), c.y + r * sin(ang)); }
}; void IntersectionPoint(const Circle& c1, const Circle& c2, Point& p1, Point& p2)
{
double d = Length(c1.c - c2.c);
double l = (c1.r*c1.r + d*d - c2.r*c2.r) / ( * d);
double h = sqrt(c1.r*c1.r - l*l);
Point mid = c1.c + unit(c2.c-c1.c) * l;
Vector t = Normal(c2.c - c1.c) * h;
p1 = mid + t;
p2 = mid - t;
} double IntersectionArea(const Circle& c1, const Circle& c2)
{
double area = 0.0;
const Circle& M = c1.r > c2.r ? c1 : c2;
const Circle& N = c1.r > c2.r ? c2 : c1;
double d = Length(c1.c-c2.c); if(d < M.r + N.r && d > M.r - N.r)
{
double Alpha = 2.0 * acos((M.r*M.r + d*d - N.r*N.r) / ( * M.r * d));
double Beta = 2.0 * acos((N.r*N.r + d*d - M.r*M.r) / ( * N.r * d));
area = ( M.r*M.r*(Alpha - sin(Alpha)) + N.r*N.r*(Beta - sin(Beta)) ) / 2.0;
}
else if(d <= M.r - N.r) area = N.area(); return area;
} struct Region_vector
{
int n;
Region v[];
void clear() { n = ; }
void add(const Region& r) { v[n++] = r; }
} *last, *cur; Circle cir[maxn];
bool del[maxn];
double r;
int n = ; bool IsOnlyOnePoint()
{
bool flag = false;
Point t;
for(int i = ; i < n; ++i)
{
for(int j = i + ; j < n; ++j)
{
if(cir[i].tangency(cir[j]))
{
t = (cir[i].c + cir[j].c) / ;
flag = true;
break;
}
}
} if(!flag) return false;
for(int i = ; i < n; ++i)
if(!cir[i].contain(t)) return false; printf("Only the point (%.2f, %.2f) is for victory.\n", t.x, t.y);
return true;
} bool solve()
{
if(IsOnlyOnePoint()) return true;
memset(del, false, sizeof(del)); for(int i = ; i < n; ++i)
for(int j = ; j < n; ++j)
{
if(del[j] || i == j) continue;
if(cir[i].contain(cir[j]))
{
del[i] = true;
break;
}
} double ans = 0.0;
for(int i = ; i < n; ++i)
{
if(del[i]) continue;
last->clear();
Point p1, p2;
for(int j = ; j < n; ++j)
{
if(del[j] || i == j) continue;
if(!cir[i].intersect(cir[j])) return false;
cur->clear();
IntersectionPoint(cir[i], cir[j], p1, p2);
double rs = Angle(p2 - cir[i].c);
double rt = Angle(p1 - cir[i].c);
if(dcmp(rs) < ) rs += * PI;
if(dcmp(rt) < ) rt += * PI;
if(last->n == )
{
if(dcmp(rt - rs) < )
{
cur->add(Region(rs, *PI));
cur->add(Region(, rt));
}
else cur->add(Region(rs, rt));
}
else
{
for(int k = ; k < last->n; ++k)
{
if(dcmp(rt - rs) < )
{
if(dcmp(last->v[k].st-rt) >= && dcmp(last->v[k].ed-rs) <= ) continue;
if(dcmp(last->v[k].st-rt) < ) cur->add(Region(last->v[k].st, std::min(last->v[k].ed, rt)));
if(dcmp(last->v[k].ed-rs) > ) cur->add(Region(std::max(last->v[k].st, rs), last->v[k].ed));
}
else
{
if(dcmp(rt-last->v[k].st <= || dcmp(rs-last->v[k].ed) >= )) continue;
cur->add(Region(std::max(rs, last->v[k].st), std::min(rt, last->v[k].ed)));
}
}
}
std::swap(cur, last);
if(last->n == ) break;
}
for(int j = ; j < last->n; ++j)
{
p1 = cir[i].get_point(last->v[j].st);
p2 = cir[i].get_point(last->v[j].ed);
ans += Cross(p1, p2) / ;
double ang = last->v[j].ed - last->v[j].st;
ans += cir[i].r * cir[i].r * (ang - sin(ang)) / ;
}
} if(dcmp(ans) == ) return false;
printf("The total possible area is %.2f.\n", ans);
return true;
} int main(void)
{
//freopen("3467in.txt", "r", stdin);
last = new Region_vector;
cur = new Region_vector;
while(scanf("%lf", &r) == )
{
Point t;
for(int i = ; i < n; ++i)
{
t.read();
cir[i] = Circle(t, r);
}
if(!solve())
puts("Poor iSea, maybe 2012 is coming!");
} return ;
}

代码君

HDU 3467 (求五个圆相交面积) Song of the Siren的更多相关文章

  1. hdu 3264 09 宁波 现场 E - Open-air shopping malls 计算几何 二分 圆相交面积 难度:1

    Description The city of M is a famous shopping city and its open-air shopping malls are extremely at ...

  2. hdu5858 Hard problem(求两圆相交面积)

    题目传送门 Hard problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  3. hdu 3264 Open-air shopping malls(圆相交面积+二分)

    Open-air shopping malls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  4. HDU 3264 Open-air shopping malls (计算几何-圆相交面积)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3264 题意:给你n个圆,坐标和半径,然后要在这n个圆的圆心画一个大圆,大圆与这n个圆相交的面积必须大于等 ...

  5. [hdu 3264] Open-air shopping malls(二分+两圆相交面积)

    题目大意是:先给你一些圆,你可以任选这些圆中的一个圆点作圆,这个圆的要求是:你画完以后.这个圆要可以覆盖之前给出的每一个圆一半以上的面积,即覆盖1/2以上每一个圆的面积. 比如例子数据,选左边还是选右 ...

  6. java求两个圆相交坐标

    最近由于项目需要,根据两个圆函数求出相交的坐标.实现代码如下,另感谢两圆求交点算法实现Java代码,虽然他所贡献的代码中存在问题,但仍有借鉴意义. 1.两个圆相交的数学求法 在中学数学中我们知道,一个 ...

  7. hdu 5120 Intersection 两个圆的面积交

    Intersection Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) P ...

  8. poj3675 求多边形与圆的面积交

    题意:给出多边形的顶点坐标.圆的圆心坐标和半径,求面积交 sol:又是模板题啦= = 注意poj的C++好像认不出hypot函数,要稍微改写一下. hypot(double x,double y):即 ...

  9. poj2546Circular Area(两圆相交面积)

    链接 画图推公式 这两种情况 都可用一种公式算出来 就是两圆都求出圆心角 求出扇形的面积减掉三角形面积 #include <iostream> using namespace std; # ...

随机推荐

  1. 【转】android 内存泄漏相关收藏博客。

    关于android内存泄漏的研究   博客建了几个月,都没有去写,一是因为当时换工作,然后又是新入职(你懂的,好好表现),比较忙:二是也因为自己没有写博客的习惯了.现在还算是比较稳定了,加上这个迭代基 ...

  2. Pentaho Data Integration笔记 (一):安装

    介绍 Pentaho Data Integration (PDI) is an extract, transform, and load (ETL) solution that uses an inn ...

  3. BZOJ 2763: [JLOI2011]飞行路线 spfa dp

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=2763 题解: d[x][kk]表示从s到x用了kk次免费机会的最少花费. 代码: #in ...

  4. 并查集 基础 AC 2014-01-14 13:37 202人阅读 评论(0) 收藏

    题目地址:http://haut.openjudge.cn/20131112/6/ 求编号最多的组 查看 提交 统计 提问 总时间限制:  1000ms  内存限制:  63353kB 描述 相邻两个 ...

  5. ios开发之触摸&手势识别

    概要: 4个触摸事件.6个手势识别.响应者链条 1.4个触摸事件 1> 触摸事件主要是针对视图的,包括 - (void)touchesBegan:(NSSet *)touches withEve ...

  6. 初学tornado之MVC版helloworld

    作者:the5fire | 标签: MVC  tornado  | 发布:2012-08-06 2:41 p.m. 文接上篇,看我一个简单的helloworld,虽然觉得这个框架着实精小,但是实际开发 ...

  7. C# 常用的工具类

    编码解码.图片与byte[].日志文件写入和读取 /// <summary> /// 将字符串编码为Base64字符串 /// </summary> /// <param ...

  8. this指针指向的彻底理解

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  9. hdu 4417 Super Mario 离线线段树

    思路:将点按值从小到大排序,询问按h从小到大排序. 在建立线段树,按h的大小更新树并得到该次查询的结果! 代码如下: #include<iostream> #include<stdi ...

  10. 缓存初解(三)---Spring3.0基于注解的缓存配置+Ehcache和OScache

    本文将构建一个普通工程来说明spring注解缓存的使用方式,关于如何在web应用中使用注解缓存,请参见: Spring基于注解的缓存配置--web应用实例 一.简介 在spring的modules包中 ...