题意:

给出 NNN 个点(二维坐标),需要求出一个点 RRR 和点 PPP(均为实数),使得 NNN 个点中有至少 ceil(N2)ceil(\frac{N}{2})ceil(2N​) 个点在以点 PPP 为圆心,半径为 RRR 的圆上。保证有解。(1≤N≤105)(1\leq N\leq 10^5)(1≤N≤105)


思路:

NNN 非常大,直接求取不可取。于是考虑随机。(计算几何中的经典套路之一,例如撒豆法猜结论)

我们随机三个点,三个点都在圆上的概率为 0.1250.1250.125,因此随机不到三个点都在圆上的概率为 0.8750.8750.875,随机 100100100 次都随机不到三个点同时在圆上的概率为 0.875100=1.5∗10−60.875^{100}=1.5*10^{-6}0.875100=1.5∗10−6,概率极低。

因此我们每次随机三个点,求这三个点的外接圆圆心,然后 O(n)O(n)O(n) 判断是否合法,最多随机 100100100 次即可得到答案。

此题唯一的坑点在于,n≤4n\leq 4n≤4 的时候需要特判。因为 n≤4n\leq 4n≤4 的时可能不存在三个点同时在圆上。比赛时就是因为这个坑点一直 wawawa 也过不去…

还有就是精度不要太高,因为开根误差太大,精度太高会 TLETLETLE。


总结:

  • 计算几何经典套路 —— 随机化(算清楚概率即可)
  • 计算几何细节处理 —— 务必小心仔细(小数据和很大数据一定要判断清楚)

代码:

#include <bits/stdc++.h>
#include <ctime>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const db EPS = 1e-4;
const int N = 1e5+1000;
using namespace std;
inline int sign(db a) {return a < -EPS ? -1 : a > EPS; } //返回-1表示a < 0, 1表示a > 0, 0表示a = 0
inline int cmp(db a, db b) {return sign(a-b); } //返回-1表示a < b, 1表示a > b,0表示 a==bint n;
struct Point{db x,y;Point() {}Point(db _x, db _y) : x(_x), y(_y) {}Point operator+(Point p) { return {x+p.x, y+p.y}; }Point operator-(Point p) { return {x-p.x, y-p.y}; }Point operator*(db d) { return {x*d, y*d}; }Point operator/(db d) { return {x/d, y/d}; }Point rotleft() { return Point(-y,x); } //逆时针旋转90度Point rotright() { return Point(y,-x); } //顺时针旋转90度db dot(Point p) { return x*p.x+y*p.y; }    //点积db det(Point p) { return x*p.y-y*p.x; } //叉积bool operator < (Point p) const {int c = cmp(x, p.x);if (c) return c == -1;return cmp(y, p.y) == -1;}db abs() { return sqrt(abs2()); }db abs2() { return x*x+y*y; }db disTo(Point p) { return (*this-p).abs(); }
}P[N];struct Line {Point s,e;Line() {}Line(Point _s, Point _e) : s(_s), e(_e) {}Point crosspoint(Line v){ //求两直线交点db a1 = (v.e-v.s).det(s-v.s);db a2 = (v.e-v.s).det(e-v.s);return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));}bool parallel(Line v){return sign((e-s).det(v.e-v.s)) == 0;}Line ajust(){Point tmp = (s+e)/2.0;Point tmp2 = tmp;db k = s.y-e.y;if(sign(k) == 0) tmp2.y += 1.0;else{if(sign(s.x-e.x) == 0) tmp2.x += 1.0;else{k = -(s.x-e.x)/(s.y-e.y);db b = tmp.y-k*tmp.x;tmp2.x = tmp.x+1.0;tmp2.y = k*tmp2.x+b;}}s = tmp; e = tmp2;return *this;}
}l1,l2,l3;int main()
{srand(time(0));int _; scanf("%d",&_);while(_--){scanf("%d",&n);rep(i,1,n) scanf("%lf %lf",&P[i].x,&P[i].y);if(n == 1){Point thp(1011.0,1011.0);db r = thp.disTo(P[1]);printf("%f %f %f\n",thp.x,thp.y,r);continue;}else if(n <= 4){Point thp = (P[1]+P[2])/2.0;db r = thp.disTo(P[1]);printf("%f %f %f\n",thp.x,thp.y,r);continue;}while(1){int p1 = rand()%n+1;int p2 = p1, p3 = p1;while(p2 == p1){p2 = rand()%n+1;}while(p3 == p1 || p3 == p2){p3 = rand()%n+1;    }l1 = {P[p1],P[p2]};l2 = {P[p1],P[p3]};l1 = l1.ajust(); l2 = l2.ajust();if(l1.parallel(l2)) continue;Point thp = l1.crosspoint(l2);db r = thp.disTo(P[p1]);int cnt = 0;rep(i,1,n){db hp = thp.disTo(P[i]);if(cmp(hp,r) == 0) cnt++;}if(cnt*2 >= n){r = thp.disTo(P[p1]);printf("%f %f %f\n",thp.x,thp.y,r);break;}}}return 0;
}

【2017CCPC哈尔滨赛区 HDU 6242】Geometry Problem【随机化】相关推荐

  1. 2017CCPC哈尔滨赛区总结

    去年CCPC两个银,结果今年成功打铜 其实战术和决策上都有严重问题,这点之前也打过广西邀请赛,只不过那时候前期怎么说还是比较顺利的 两场队友一样,就简称Y和Q吧 其实在比赛前一天晚上,就跟队友说:没有 ...

  2. 2017CCPC哈尔滨 M:Geometry Problem(随机)

    题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1013&cid=784 题意: 给你n个点,找出一个圆满足至少 ...

  3. hdu 1086 A - You can Solve a Geometry Problem too (线段的规范相交非规范相交)

    A - You can Solve a Geometry Problem too Time Limit:1000MS     Memory Limit:32768KB     64bit IO For ...

  4. HDU 1086 You can Solve a Geometry Problem too

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3276 ...

  5. HDU 1086 You can Solve a Geometry Problem too (判断线段交叉,线段跨立)

    You can Solve a Geometry Problem too   Time Limit:1000MS     Memory Limit:32768KB     64bit IO Forma ...

  6. 2017CCPC哈尔滨 H:A Simple Stone Game

    题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1008&cid=784 题意: 给你n个正整数,每次可以将某个 ...

  7. 2017CCPC哈尔滨 F:Permutation(构造)

    题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1006&cid=784 题意: 让你构造一个1到n的全排列,满 ...

  8. 2017CCPC哈尔滨 D:X-Men

    题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=784 题意: 给一棵树,某些点上有人,每个时 ...

  9. 2017CCPC哈尔滨 B:K-th Number(二分)

    题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=784 题意: 给你n个数,之后求出所有连续区 ...

  10. 2017CCPC哈尔滨 A:Palindrome(manacher+树状数组)

    题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1001&cid=784 题意: 给你一个串s,求出满足S[i] ...

最新文章

  1. Servlet 传输中文乱码解决方法
  2. linux pcie热插拔驱动_Linux安装TLP-高级电源管理工具
  3. GDI+中发生一般性错误
  4. 多个Main函数的应用程序
  5. Java多线程(二)之Atomic:原子变量与原子类
  6. 为QT的Webkit 编写插件
  7. 电池技术为什么如此高深莫测,以至于一直是手机等相关行业的短板?
  8. antd 日期时间选择_【UI设计】日期选择器的常见样式总结
  9. poi导出word模板项目实例(一个文件)
  10. [WTL] 改变右击SysMenu后弹出的菜单
  11. 如何让Mac在 Finder 顶部显示完整的文件路径
  12. WCF分布式安全开发实践(10):消息安全模式之自定义用户名密码:Message_UserNamePassword_WSHttpBinding...
  13. 网站可行性报告范文_邢台写可行性报告写立项报告范文-环建
  14. 三星手机如何分屏_艺术大片如何拍?快拜三星Galaxy S20 5G系列为师|三星|摄像头|手机|远景...
  15. 工作组计算机如何设置文件共享,怎么设置办公室几台电脑文件共享?
  16. 科技爱好者周刊:第 61 期
  17. Lombok插件下载与离线安装
  18. 我父亲给我姐姐带来了一台计算机英语,写我的家人的作文400字
  19. 主数据管理平台功能模型介绍
  20. ESP32 DEVKIT V1 资料分享-原理图+引脚图

热门文章

  1. Android屏幕尺寸(来自网络整理)
  2. Sql Server 全文检索
  3. Solaris下用Bind安装和配置DNS
  4. 基于C#的Access MsSQL MySQL 三种数据库访问演示(含源文件Demo)
  5. java 文件描述符_文件描述符了解一下
  6. eclipse的控制台显示有问题,关闭Limit console output
  7. python数据可视化仪表盘,Python 数据可视化?
  8. 用74l138实现一个一位全减器_用react实现一个仿ionic button组件
  9. android中的actionbar,android中开启actionbar的两种方法
  10. python常用字符串_Python中最常用的字符串方法!