zoukankan      html  css  js  c++  java
  • 2961: 共点圆

    2961: 共点圆

    Time Limit: 30 Sec  Memory Limit: 256 MB
    Submit: 875  Solved: 375
    [Submit][Status][Discuss]

    Description

      在平面直角坐标系中,Wayne需要你完成n次操作,操作只有两种:
      1.0 x y。表示在坐标系中加入一个以(x, y)为圆心且过原点的圆。
      2.1 x y。表示询问点(x, y)是否在所有已加入的圆的内部(含圆周),且至少在一个圆内部(含圆周)。
      为了减少你的工作量,题目保证圆心严格在x轴上方(纵坐标为正),且横坐标非零。

    Input

      第1行一个整数n。
      接下来n行,每行第一个数是0或1,分别表示两种操作。
      接着有两个实数x和y,具体意义见题面。

    Output

      对于每个询问操作,如果点在所有已加入的圆内(或圆周上),则输出“Yes”(不含引号);否则输出“No”(不含引号)。

    Sample Input

    5
    0 2.0000 3.0000
    0 4.0000 1.0000
    1 1.000000 1.000000
    0 -3.0000 2.0000
    1 1.000000 1.000000

    Sample Output

    Yes
    No

    HINT



    对于100%的数据,n≤500000,所有坐标绝对值不超过10000。

      输入数据保证圆心纵坐标为正,横坐标非零。

      圆心坐标保留4位小数,询问点坐标保留6位小数,请选手注意控制精度。




    Source

    思路来自:这里

    推荐论文:许昊然 《浅谈数据结构题的几个非经典解法》

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #define pf(x) ((x)*(x))
    #define IN inline
    #define inf 1e20
    using namespace std;
    const int N=5e5+5;
    const double eps=1e-10;
    struct node{
        int opt,p,id;
        double x,y,k;
        bool operator <(const node &t)const{
            return k<t.k;
        }
    }a[N],b[N];
    int n,cnt,q[N];
    bool ok[N];char s1[30],s2[30],s3[30];
    double getk(int x,int y){
        if(fabs(a[x].x-a[y].x)<eps) return inf;
        return (a[x].y-a[y].y)/(a[x].x-a[y].x);
    }
    double dis(int x,int y){
        return pf(a[x].x-a[y].x)+pf(a[x].y-a[y].y);
    }
    //不知道为什么4360 ms巨慢(有人跑788 ms)太弱了! 
    void CDQ(int l,int r){
        if(l==r) return ;
        int mid=l+r>>1,i=1,k=mid+1,j=l,tp=0;
        for(i=l;i<=r;i++){
            if(a[i].id<=mid)
                b[j++]=a[i];
            else
                b[k++]=a[i];
        }
        for(i=l;i<=r;i++) a[i]=b[i];
        CDQ(l,mid);//本题只需要维护上凸包,下凸包是x轴 
        for(i=l;i<=mid;i++) if(!a[i].opt){
            for(;tp>1&&getk(q[tp-1],i)<getk(q[tp-1],q[tp])+eps;tp--);
            q[++tp]=i;
        }
        for(j=1,i=mid+1;i<=r;i++) if(a[i].opt){
            for(;j<tp&&getk(q[j],q[j+1])<a[i].k;j++);
            if(j<=tp&&dis(q[j],0)<dis(q[j],i)) ok[a[i].p]=0;
        }
        CDQ(mid+1,r);
        for(i=j=l,k=mid+1;i<=r;i++){
            if((j<=mid&&a[j].x<a[k].x)||k>r)
                b[i]=a[j++];
            else
                b[i]=a[k++];
        }
        for(i=l;i<=r;i++) a[i]=b[i];
    }
    int main(){
        scanf("%s",s1);n=atoi(s1);
        bool flag=0;
        for(int i=1;i<=n;i++){
            scanf("%s%s%s",s1,s2,s3);
            a[i].opt=s1[0]-'0';a[i].x=atof(s2);a[i].y=atof(s3);
            if(a[i].opt) a[i].p=++cnt,ok[cnt]=flag;else flag=1;
            a[i].k=-a[i].x/a[i].y;a[i].id=i;
        }
        sort(a+1,a+n+1);CDQ(1,n);
        for(int i=1;i<=cnt;i++) puts(ok[i]?"Yes":"No");
        return 0;
    }
  • 相关阅读:
    LNK2001: unresolved external symbol ... virtual ...
    pygments
    cygwin Mingw
    [转]__attribute__((format (printf, 2, 3))
    [转] C和C++混合编程
    [转]网络包的流转
    [转]程序是如何运行起来的
    [转]Makefile中 .PHONY的作用
    [转]makefile学习
    [转] makefile 中 = := ?= += 区别
  • 原文地址:https://www.cnblogs.com/shenben/p/6347773.html
Copyright © 2011-2022 走看看