[POJ 2588] Snakes

同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 0;
    return x<0?-1:1;
}
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))==0 && dcmp(fabs(y-p.y))==0;
    }
    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=2*(A*B+C*D),G=B*B+D*D-r*r;
        double delta=F*F-4*E*G;
        if(dcmp(delta)<0) return make_pair(0,res);
        if(dcmp(delta)==0){
            res.push_back(l.GetPoint(-F/(2*E)));
            return make_pair(1,res);
        }
        res.push_back(l.GetPoint((-F-sqrt(delta))/(2*E)));
        res.push_back(l.GetPoint((-F+sqrt(delta))/(2*E)));
        return make_pair(2,res);
    }
    /* -1表示重合,0表示相离,1表示相切,2表示相交 */
    int operator & (Circle C){
        double d=(c-C.c).length();
        if(dcmp(d)==0){
            if(dcmp(r-C.r)==0) return -1;
            return 0;
        }
        if(dcmp(r+C.r-d)<0) return 0;
        if(dcmp(fabs(r-C.r)-d)>0) return 0;
        double a=(C.c-c).angle();
        double da=acos((r*r+d*d-C.r*C.r)/(2*r*d));
        Point p1=GetPoint(a-da),p2=GetPoint(a+da);
        if(p1==p2) return 1;
        return 2;
    }
};

int n;
int f[N];
Line up,down;
Line lft,rgt;
Circle c[N];

void init()
{
    for(int i=0;i<=n+1;i++) f[i]=i;
    up=Line(Point(0,1000),Point(1000,1000));
    down=Line(Point(0,0),Point(1000,0));
    lft=Line(Point(0,0),Point(0,1000));
    rgt=Line(Point(1000,0),Point(1000,1000));
}
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=1;i<=n;i++) scanf("%lf%lf%lf",&c[i].c.x,&c[i].c.y,&c[i].r);
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                if((c[i]&c[j])!=0){
                    UN(i,j);
                }
            }
        }
        //上边界
        for(int i=1;i<=n;i++){
            pair<int,vector<Point> > res=c[i].CircleInterLine(up);
            if(res.first!=0) UN(0,i);
        }
        //下边界
        for(int i=1;i<=n;i++){
            pair<int,vector<Point> > res=c[i].CircleInterLine(down);
            if(res.first!=0) UN(i,n+1);
        }
        if(Find(0)==Find(n+1)){ //出不去
            printf("Bill will be bitten.\n");
            continue;
        }
        //左边界
        vector<Point> p1,p2;
        p1.push_back(Point(0,1000));
        p2.push_back(Point(1000,1000));
        for(int i=1;i<=n;i++){
            pair<int,vector<Point> > res1=c[i].CircleInterLine(lft);
            pair<int,vector<Point> > res2=c[i].CircleInterLine(rgt);
            if(res1.first!=0){
                while(!res1.second.empty()){
                    if(res1.second.back().y>=0 && res1.second.back().y<=1000 && Find(i)==Find(0))
                        p1.push_back(res1.second.back());
                    res1.second.pop_back();
                }
            }
            if(res2.first!=0){
                while(!res2.second.empty()){
                    if(res2.second.back().y>=0 && res2.second.back().y<=1000 && Find(i)==Find(0))
                        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[0].y,p2[0].y);
    }
    return 0;
}
时间: 2024-10-08 04:50:37

[POJ 2588] Snakes的相关文章

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

题目链接:http://poj.org/problem?id=2588 Snakes Time Limit: 1000MS   Memory Limit: 65536K   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

POJ 2337 Catenyms (有向图欧拉通路)

Catenyms Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9914   Accepted: 2588 Description A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For e

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)

POJ——T2271 Guardian of Decency

http://poj.org/problem?id=2771 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5932   Accepted: 2463 Description Frank N. Stein is a very conservative high-school teacher. He wants to take some of his students on an excursion, but he is

POJ——T2446 Chessboard

http://poj.org/problem?id=2446 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18560   Accepted: 5857 Description Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of c

poj 1088 滑雪 DP(dfs的记忆化搜索)

题目地址:http://poj.org/problem?id=1088 题目大意:给你一个m*n的矩阵 如果其中一个点高于另一个点 那么就可以从高点向下滑 直到没有可以下滑的时候 就得到一条下滑路径 求最大的下滑路径 分析:因为只能从高峰滑到低峰,无后效性,所以每个点都可以找到自己的最长下滑距离(只与自己高度有关).记忆每个点的最长下滑距离,当有另一个点的下滑路径遇到这个点的时候,直接加上这个点的最长下滑距离. dp递推式是,dp[x][y] = max(dp[x][y],dp[x+1][y]+

POJ 1385 计算几何 多边形重心

链接: http://poj.org/problem?id=1385 题意: 给你一个多边形,求它的重心 题解: 模板题,但是不知道为啥我的结果输出的确是-0.00 -0.00 所以我又写了个 if (ans.x == 0) ans.x = 0 感觉好傻逼 代码: 1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <queue> 5 #include <stack> 6

POJ 1741 Tree(树的点分治,入门题)

Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21357   Accepted: 7006 Description Give a tree with n vertices,each edge has a length(positive integer less than 1001).Define dist(u,v)=The min distance between node u and v.Give an in