隐藏页面特效

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; }

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/6347773.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(475)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示