bzoj2289: 【POJ Challenge】圆,圆,圆

Description

1tthinking随便地画了一些圆. ftiasch认为这些圆有交集(面积非零)的可能性不大。因为他实在画了太多圆,所以你被请来判断是否存在交集。

Input

第1行,一个整数 N (1 ≤ N ≤ 105), 圆的数量。

第2到 N 行: 三个整数 Xi, Yi, Ri, 圆心在 (Xi, Yi), 半径为 Ri 的圆。

Output

如果存在面积非零的交集,则输出 "YES",否则输出 "NO"。

首先可以确定如果有相交,x坐标一定在区间[max(x[i]-r[i]),min(x[i]+r[i])]内

取这个区间中点M,在直线x=M上,若所有圆在这条线上有不为0的交集则可以判断存在面积非0的交集

否则找出一对圆在x=M上不相交,若两圆相离/相切则可以判断无解,否则把区间缩小到这两个圆交集所在的x坐标区间递归计算

每次缩小区间至少缩小一半,且圆的坐标和半径是整数,因此复杂度是可以保证的

#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef double ld;
const ld _0=1e-6l;
const int N=100010;
int n;
ld x[N],y[N],r[N];
ld L,R;
int read(){
    int x=0,c=getchar(),f=1;
    while(c>57||c<48){if(c==‘-‘)f=-1;c=getchar();}
    while(c>47&&c<58)x=x*10+c-48,c=getchar();
    return x*f;
}
void get(int id,ld X,ld&a,ld&b){
    X-=x[id];
    X=sqrt(r[id]*r[id]-X*X);
    a=y[id]-X;
    b=y[id]+X;
}
bool chk(ld X,int a,int b){
    if(fabs(X-x[a])>r[a]||fabs(X-x[b])>r[b])return 0;
    ld a1,a2,b1,b2;
    get(a,X,a1,a2);
    get(b,X,b1,b2);
    return a2>b1&&a1<b2;
}
void chk(int a,int b){
    ld xd=x[b]-x[a],yd=y[b]-y[a];
    ld d=sqrt(xd*xd+yd*yd);
    if(d+_0>r[a]+r[b]){
        puts("NO");
        exit(0);
    }
    ld s=(r[a]+r[b]+d)/2.;
    ld h=2*sqrt(s*(s-r[a])*(s-r[b])*(s-d))/d;
    ld m=x[a]+xd*sqrt(r[a]*r[a]-h*h)/d,c=h*fabs(yd)/d;
    if(d*d+r[a]*r[a]<r[b]*r[b])m=x[a]*2-m;
    ld lx=m-c,rx=m+c;
    if(lx>x[a]-r[a]&&chk(x[a]-r[a]+_0,a,b))lx=x[a]-r[a];
    if(lx>x[b]-r[b]&&chk(x[b]-r[b]+_0,a,b))lx=x[b]-r[b];
    if(rx<x[a]+r[a]&&chk(x[a]+r[a]-_0,a,b))rx=x[a]+r[a];
    if(rx<x[b]+r[b]&&chk(x[b]+r[b]-_0,a,b))rx=x[b]+r[b];
    if(lx>L)L=lx;
    if(rx<R)R=rx;
}
int main(){
    n=read();
    for(int i=0;i<n;i++){
        x[i]=read();
        y[i]=read();
        r[i]=read();
    }
    L=x[0]-r[0],R=x[0]+r[0];
    for(int i=1;i<n;i++){
        if(L<x[i]-r[i])L=x[i]-r[i];
        if(R>x[i]+r[i])R=x[i]+r[i];
    }
    while(1){
        if(L+_0>R){
            puts("NO");
            return 0;
        }
        ld M=(L+R)/2.;
        ld y1,y2,a1,a2;
        get(0,M,y1,y2);
        for(int i=1;i<n;i++){
            get(i,M,a1,a2);
            if(a1>y1)y1=a1;
            if(a2<y2)y2=a2;
            if(y1+_0>y2){
                for(int j=0;j<i;j++){
                    get(j,M,y1,y2);
                    if(y1>=a2-_0||y2<=a1+_0){
                        chk(i,j);
                        goto re;
                    }
                }
            }
        }
        puts("YES");
        return 0;
        re:;
    }
}
时间: 2024-08-20 20:44:23

bzoj2289: 【POJ Challenge】圆,圆,圆的相关文章

2292: 【POJ Challenge 】永远挑战

2292: [POJ Challenge ]永远挑战 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 553  Solved: 230[Submit][Status][Discuss] Description lqp18_31和1tthinking经常出题来虐ftiasch.有一天, lqp18_31搞了一个有向图,每条边的长度都是1. 他想让ftiasch求出点1到点 N 的最短路."水题啊.", ftiasch这么说道. 所以1tth

BZOJ2288: 【POJ Challenge】生日礼物

2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 771  Solved: 238[Submit][Status][Discuss] Description ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知道选择元素之和的最大值.你能帮助她吗? Input

bzoj2287【POJ Challenge】消失之物(dp+补集转化,好题)

2287: [POJ Challenge]消失之物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 657  Solved: 382[Submit][Status][Discuss] Description ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN. 由于她的疏忽, 第 i 个物品丢失了. “要使用剩下的 N - 1 物品装满容积为 x 的背包,有几种方法呢?” -- 这是经典的问题了.她把答案记为 Count(

【BZOJ 2288】 2288: 【POJ Challenge】生日礼物 (贪心+优先队列+双向链表)

2288: [POJ Challenge]生日礼物 Description ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知道选择元素之和的最大值.你能帮助她吗? Input 第1行,两个整数 N (1 ≤ N ≤ 105) 和 M (0 ≤ M ≤ 105), 序列的长度和可以选择的部分. 第2行, N 个整数 A1, A2, ..., AN (0

BZOJ2295: 【POJ Challenge】我爱你啊

2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 126  Solved: 90[Submit][Status] Description ftiasch是个十分受女生欢迎的同学,所以她总是收到许多情书.虽然她十分有魅力,然而她却是个低调的人.因此她从来不会告诉别人她到底收到了多少情书. ftiasch的好朋友1tthinking想知道她到底收到了多少情书.1tthinking知道,ftiasch每次收

BZOJ2292: 【POJ Challenge 】永远挑战

2292: [POJ Challenge ]永远挑战 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 513  Solved: 201[Submit][Status] Description lqp18_31和1tthinking经常出题来虐ftiasch.有一天, lqp18_31搞了一个有向图,每条边的长度都是1. 他想让ftiasch求出点1到点 N 的最短路."水题啊.", ftiasch这么说道. 所以1tthinking把某些

BZOJ2287: 【POJ Challenge】消失之物

2287: [POJ Challenge]消失之物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 254  Solved: 140[Submit][Status] Description ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN. 由于她的疏忽, 第 i 个物品丢失了. “要使用剩下的 N - 1 物品装满容积为 x 的背包,有几种方法呢?” -- 这是经典的问题了.她把答案记为 Count(i, x) ,想要

BZOJ2293: 【POJ Challenge】吉他英雄

2293: [POJ Challenge]吉他英雄 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 80  Solved: 59[Submit][Status] Description 1tthinking 特别喜欢玩‘guitar hero’. 现在有 N (2 ≤ N ≤ 50) 首歌在这个游戏中,他们被标为 1 到 N. 游戏会随机把歌曲分组 P. 更详细的说, 对于 P = <P1, P2, ... PN>, 游戏会在第 i 首之后播放第

BZOJ 2287 【POJ Challenge】消失之物

2287: [POJ Challenge]消失之物 Description ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN. 由于她的疏忽, 第 i 个物品丢失了. “要使用剩下的 N - 1 物品装满容积为 x 的背包,有几种方法呢?” -- 这是经典的问题了.她把答案记为 Count(i, x) ,想要得到所有1 <= i <= N, 1 <= x <= M的 Count(i, x) 表格. Input 第1行:两个整数 N (1 ≤ N ≤ 2

BZOJ 2287: 【POJ Challenge】消失之物( 背包dp )

虽然A掉了但是时间感人啊.... f( x, k ) 表示使用前 x 种填满容量为 k 的背包的方案数, g( x , k ) 表示使用后 x 种填满容量为 k 的背包的方案数. 丢了第 i 个, 要填满容量为 k 的背包 , 则 ans( i , k ) = ∑ f( i - 1, h ) * g( i + 1 , k - h ) ( 0 <= h <= k ) 这样就转化为经典的背包问题了 f( x , k ) = f( x - 1 , k ) + f( x - 1 , k - w( x