codeforces 159 D(几何二分)

我就是我 2022-05-04 23:58 264阅读 0赞

传送门

题意:给你n个点,问与x轴相切,并且包含这n个点的圆的最小半径是多少。

思路:真是做的的怀疑人生。思路是首先判断点是否在一边。

如果在一边一定有解,二分半径R,这时候圆心在y=R的线上,对于每个点,

我们移动圆就会发现包含这个点吗圆心轨迹是一个线段,我们只需要对每个点的区域

交集,就可以判断存不存在圆心。

但是奇怪的是,本地跟评测机跑的不一样,还有一点不明白的是,

在二分的时候为什么用精度会t,而需要直接设置循环次数。

精度1e-10,这样复杂度是log(1e28)也就100次循环啊,不是很理解

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=1e5+10;
  4. const double eps=1e-10;
  5. const double INF=1e18;
  6. struct Point{
  7. double x, y;
  8. }p[N];
  9. int n;
  10. bool check(double R){
  11. double l=-1e9, r=1e9;
  12. for(int i=1; i<=n; i++){
  13. if(p[i].y>2.0*R)return false;
  14. double d=p[i].y-R;
  15. double dx;
  16. dx=sqrt(R+d)*sqrt(R-d);
  17. l=max(l, p[i].x-dx), r=min(r, p[i].x+dx);
  18. if(l>r) return false;
  19. }
  20. return true;
  21. }
  22. int main(){
  23. scanf("%d", &n);
  24. bool up=false, down=false;
  25. for(int i=1; i<=n; i++){
  26. scanf("%lf%lf", &p[i].x, &p[i].y);
  27. if(p[i].y>0) up=true;
  28. else{
  29. down=true;
  30. p[i].y=-p[i].y;
  31. }
  32. }
  33. if(up&&down){
  34. puts("-1");
  35. return 0;
  36. }
  37. double l=0, r=INF, ans=-1;
  38. for(int i=1; i<=300; i++){
  39. double mid=(l+r)/2.0;
  40. if(check(mid)){
  41. ans=mid;
  42. r=mid;
  43. }
  44. else{
  45. l=mid;
  46. }
  47. }
  48. printf("%.10lf\n", ans);
  49. return 0;
  50. }

发表评论

表情:
评论列表 (有 0 条评论,264人围观)

还没有评论,来说两句吧...

相关阅读

    相关 CodeForces1214D

    [CodeForces1214D][] 这个题据我所知有两种比较优秀的做法. 第一种是\\(DP\\)统计每个点的路径数,然后找出必经点,再从必经点开始\\(bfs\\

    相关 codeforces 567D

    满足二分的条件,如果当前的断点不符合条件,那么后面的一定不符合条件,如果当前的符合条件,那么后面的可能还有符合条件的。 二分的过程中对断点进行排序,判断每个区间能放多少

    相关 Codeforces 496D

    题意 -------------------- 进行若干场比赛,每次比赛两人对决,赢的人得到1分,输的人不得分,先得到t分的人获胜,开始下场比赛,某个人率先赢下s场比赛

    相关 codeforces 159 D(几何二分)

    [传送门][Link 1] 题意:给你n个点,问与x轴相切,并且包含这n个点的圆的最小半径是多少。 思路:真是做的的怀疑人生。思路是首先判断点是否在一边。 如果在一边一定