您的位置:首页 > 其它

ZCMU—1792

2017-01-11 19:13 316 查看

Problem C: Problem C - Snakes

Time Limit: 1 Sec  Memory Limit:
128 MB
Submit: 5  Solved: 3

[Submit][Status][Web
Board]

Description

Problem C - Snakes

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?

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.

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."

Input

Output

Sample Input

3500 500 4990 0 9991000 1000 200

Sample Output

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

【分析】

题目难懂...题意是给你很多个蛇的攻击范围,以x,y,为圆心,半径为r,问你一个人从场地西边进,能不能从东边出去。

题意弄懂之后就会发现题目内容其实很简单,就是给你n个圆,问你有没有相交的圆能把上边界和下边界连起来。

考虑并查集,相交的圆属于同一个堆,最后判断上边界和下边界是否相连就可以了,但是这里有一点挺麻烦的就是如何判断入点和出点,题目里要求说入点和出点都要小,所以去判断一下每个堆的点与西边和东边相交的位置,求个最小的就可以了。题意很简单。。写起来挺复杂的其实。。。poj上我WA了7次才ac。。大概是我数学水平太差...

【代码】

#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
struct xx{
double x,y,r;
}a[2000];
int f[2000];
int find(int x)
{
if (f[x]==x) return x;
return f[x]=find(f[x]);
}
int main()
{
int n;scanf("%d",&n);
for (int i=0;i<=n;i++) f[i]=i;
f[1111]=1111;
for (int i=1;i<=n;i++)
{
scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].r);
for (int j=1;j<i;j++)
if (sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y))-a[i].r-a[j].r<=0)
f[find(j)]=find(i);
if (fabs(a[i].y)-a[i].r<0) f[find(1111)]=f[find(i)];
if (fabs(fabs(a[i].y)-1000)-a[i].r<0) f[find(i)]=f[find(0)];
}
if (find(1111)==find(0)) printf("Bill will be bitten.");
else
{
double start=1000,end=1000;
for (int i=1;i<=n;i++)
{
double d=fabs(a[i].x-1000);
if (a[i].x-a[i].r<0 && find(i)==find(0) && a[i].y-sqrt(a[i].r*a[i].r-a[i].x*a[i].x)<start) start=a[i].y-sqrt(a[i].r*a[i].r-a[i].x*a[i].x);
if (d-a[i].r<0 && find(i)==find(0) && a[i].y-sqrt(a[i].r*a[i].r-d*d)<end) end=a[i].y-sqrt(a[i].r*a[i].r-d*d);
}
printf("Bill enters at (0.00, %0.2f) and leaves at (1000.00, %0.2f).",start,end);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: