同swustoj 8

Snakes
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 1015   Accepted: 341

Description

Buffalo Bill wishes to cross a 1000x1000 square field. A number of snakes are on the field at various positions, and each snake can strike a particular distance in any direction. Can Bill make the trip without being bitten?

Input

Assume that the southwest corner of the field is at (0,0) and the northwest corner at (0,1000). The input consists of a line containing n <= 1000, the number of snakes. A line follows for each snake, containing three real numbers: the (x,y) location of the snake and its strike distance. The snake will bite anything that passes closer than this distance from its location.

Output

Bill must enter the field somewhere between the southwest and northwest corner and must leave somewhere between the southeast and northeast corners.

If Bill can complete the trip, give coordinates at which he may enter and leave the field. If Bill may enter and leave at several places, give the most northerly. If there is no such pair of positions, print "Bill will be bitten."

Sample Input

3
500 500 499
0 0 999
1000 1000 200

Sample Output

Bill enters at (0.00, 1000.00) and leaves at (1000.00, 800.00).

并查集+计算几何

#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstdio>
using namespace std; #define PI acos(-1.0)
#define EPS 1e-8
#define N 1010 int dcmp(double x)
{
if(fabs(x)<EPS) return ;
return x<?-:;
}
struct Point
{
double x,y;
Point (){}
Point (double x,double y):x(x),y(y){}
Point operator - (Point p){
return Point(x-p.x,y-p.y);
}
bool operator == (Point p){
return dcmp(fabs(x-p.x))== && dcmp(fabs(y-p.y))==;
}
double operator * (Point p){
return x*p.x+y*p.y;
}
double operator ^ (Point p){
return x*p.y-y*p.x;
}
double length(){
return sqrt(x*x+y*y);
}
double angle(){
return atan2(y,x);
}
bool operator <(const Point &p)const{
return y<p.y;
}
};
struct Line
{
Point s,e;
Line (){}
Line (Point s,Point e):s(s),e(e){}
Point GetPoint(double t){
return Point(s.x+(e.x-s.x)*t,s.y+(e.y-s.y)*t);
}
};
struct Circle
{
Point c;
double r;
Circle(){}
Circle(Point c,double r):c(c),r(r){}
Point GetPoint(double a){
return Point(c.x+cos(a)*r,c.y+sin(a)*r);
}
/* 0表示相离,1表示相切,2表示相交 */
pair<int,vector<Point> > CircleInterLine(Line l){
vector<Point> res;
double A=l.e.x-l.s.x,B=l.s.x-c.x,C=l.e.y-l.s.y,D=l.s.y-c.y;
double E=A*A+C*C,F=*(A*B+C*D),G=B*B+D*D-r*r;
double delta=F*F-*E*G;
if(dcmp(delta)<) return make_pair(,res);
if(dcmp(delta)==){
res.push_back(l.GetPoint(-F/(*E)));
return make_pair(,res);
}
res.push_back(l.GetPoint((-F-sqrt(delta))/(*E)));
res.push_back(l.GetPoint((-F+sqrt(delta))/(*E)));
return make_pair(,res);
}
/* -1表示重合,0表示相离,1表示相切,2表示相交 */
int operator & (Circle C){
double d=(c-C.c).length();
if(dcmp(d)==){
if(dcmp(r-C.r)==) return -;
return ;
}
if(dcmp(r+C.r-d)<) return ;
if(dcmp(fabs(r-C.r)-d)>) return ;
double a=(C.c-c).angle();
double da=acos((r*r+d*d-C.r*C.r)/(*r*d));
Point p1=GetPoint(a-da),p2=GetPoint(a+da);
if(p1==p2) return ;
return ;
}
}; int n;
int f[N];
Line up,down;
Line lft,rgt;
Circle c[N]; void init()
{
for(int i=;i<=n+;i++) f[i]=i;
up=Line(Point(,),Point(,));
down=Line(Point(,),Point(,));
lft=Line(Point(,),Point(,));
rgt=Line(Point(,),Point(,));
}
int Find(int x)
{
if(x!=f[x]) f[x]=Find(f[x]);
return f[x];
}
void UN(int x,int y)
{
x=Find(x);
y=Find(y);
if(x!=y) f[x]=y;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=;i<=n;i++) scanf("%lf%lf%lf",&c[i].c.x,&c[i].c.y,&c[i].r);
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if((c[i]&c[j])!=){
UN(i,j);
}
}
}
//上边界
for(int i=;i<=n;i++){
pair<int,vector<Point> > res=c[i].CircleInterLine(up);
if(res.first!=) UN(,i);
}
//下边界
for(int i=;i<=n;i++){
pair<int,vector<Point> > res=c[i].CircleInterLine(down);
if(res.first!=) UN(i,n+);
}
if(Find()==Find(n+)){ //出不去
printf("Bill will be bitten.\n");
continue;
}
//左右边界
vector<Point> p1,p2;
p1.push_back(Point(,));
p2.push_back(Point(,));
for(int i=;i<=n;i++){
pair<int,vector<Point> > res1=c[i].CircleInterLine(lft);
pair<int,vector<Point> > res2=c[i].CircleInterLine(rgt);
if(res1.first!=){
while(!res1.second.empty()){
if(res1.second.back().y>= && res1.second.back().y<= && Find(i)==Find())
p1.push_back(res1.second.back());
res1.second.pop_back();
}
}
if(res2.first!=){
while(!res2.second.empty()){
if(res2.second.back().y>= && res2.second.back().y<= && Find(i)==Find())
p2.push_back(res2.second.back());
res2.second.pop_back();
}
}
}
int i,j;
sort(p1.begin(),p1.end());
sort(p2.begin(),p2.end());
printf("Bill enters at (0.00, %.2f) and leaves at (1000.00, %.2f).\n",p1[].y,p2[].y);
}
return ;
}

[POJ 2588] Snakes的更多相关文章

  1. [POJ 2588]--Snakes(并查集)

    题目链接:http://poj.org/problem?id=2588 Snakes Time Limit: 1000MS   Memory Limit: 65536K   Description B ...

  2. POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7644   Accepted: 2798 ...

  3. POJ 2356. Find a multiple 抽屉原理 / 鸽巢原理

    Find a multiple Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7192   Accepted: 3138   ...

  4. POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22286 ...

  5. POJ 1753. Flip Game 枚举or爆搜+位压缩,或者高斯消元法

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37427   Accepted: 16288 Descr ...

  6. POJ 3254. Corn Fields 状态压缩DP (入门级)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9806   Accepted: 5185 Descr ...

  7. POJ 2739. Sum of Consecutive Prime Numbers

    Sum of Consecutive Prime Numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20050 ...

  8. POJ 2255. Tree Recovery

    Tree Recovery Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11939   Accepted: 7493 De ...

  9. POJ 2752 Seek the Name, Seek the Fame [kmp]

    Seek the Name, Seek the Fame Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17898   Ac ...

随机推荐

  1. 修正 phpcmsv9 VIP过期日期为1970

    打开 phpcms/modules/member/member.php 找到 $form_overdudate = form::date('info[overduedate]', date('Y-m- ...

  2. MySQL的alter的使用

    ALTER TABLE 语句用于在已有的表中添加.修改或删除列 1.ADD [COLUMN] column name (column definitions) [FIRST or AFTER colu ...

  3. 九度OJ - 题目1481:Is It A Tree?

    题目描述: A tree is a well-known data structure that is either empty (null, void, nothing) or is a set o ...

  4. Hibernate从入门到精通(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类似,只是在多 ...

  5. dnf脚本的研究

    [player number] 2 8  [pvp start area]0 0 0 00 0 0 00 0 0 0[dungeon]62[/dungeon][type] `[normal]`[gre ...

  6. SDIBT 3237 Boring Counting( 划分树+二分枚举 )

    http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=3237 Problem H:Boring Counting Time Limit: 3 Sec  ...

  7. SQL的集合运算符介绍

    最近学习了SQL SERVER方面的知识,毕竟做Web应用,少不了跟数据库打交道.学习的来源主要是<程序员的SQL金典>这本书. 今天介绍数据库里面的集合运算符,它是指匹配集合的每一个结果 ...

  8. linux samba.tar.gz安装和配置

    安装步骤: 1. tar -xzvf samba-3.5.10.tar.gz2. cd samba-3.5.103. cd source34. ./autogen.sh  如果出现:./autogen ...

  9. redis其他问题

    如何解决redis高并发客户端频繁time out? 现在业务上每天有5亿+的请求,平时redis的操作在2K+每秒左右.到了高峰有3K+,这时候客户端就会频繁的报connect time out的异 ...

  10. classpath、path、JAVA_HOME的作用及JAVA环境变量配置

    CLASSPATH是什么?它的作用是什么? 它是javac编译器的一个环境变量.它的作用与import.package关键字有关.当你写下improt java.util.*时,编译器面对import ...