【计算几何】信号覆盖
来源:互联网 发布:费曼 知乎 编辑:程序博客网 时间:2024/04/29 15:39
调了很久很久。。。比较难。需要进行多次转换。
朴素O(n^4)过4组,但是因为我用getint,没法读负数,同时有个地方乘法写成加法,同时算半径算成了边长,所以零分。
比较有启发性,作为一道计算几何题目。本来是三角形和点的关系,可以转化成构造四边形。
在本题中,凹多边形和凸多边形是不同的,必须单独讨论,由图可知,凸多边形可以有两个圆满足这个要求,凹多边形只有一个。
设凸多边形和凹多边形个数分别是P、Q。
所以只需要求其一即可。此处求Q较容易。
我们枚举每一个点,求包含这个点的三角形的数量,累加即为Q。
再次转换,求包含某一点的所有圆的时候,我们求不包含这个点的所有圆,可以用叉乘来实现,当然需要极角排序(这里有一点要注意,因为用叉乘比较是相对的,而不是绝对的,考虑一些极角排序好了的向量,大小关系是循环的。。。因此排序貌似只能用快排,不能用堆排等,包括sort)
(对上面的讨论,有一点误区需要注意,不能直接根据不包含某点的所有三角形个数来求P,这一点想了很久才想清楚,因为一个四边形,枚举四个点的时候,这个四边形会被计算四次,所以除以要除以四)
就是不知为何,一开始记录x和y用long出错了,用double就对了。
#include <algorithm>#include <cmath>#include <cstdio>using std::sort;long long c[1600][10];struct pos;long crp(const pos& a,const pos& b);struct pos{ double x; double y; bool operator<(const pos& p2) const { return x*p2.y-p2.x*y < 0; }};long n;pos a[3010];pos b[3010];long long X = 0;inline void swap(pos& a,pos& b){ pos t = a; a = b; b = t;}void Qsort(int l,int r){ int i=l,j=r; pos mid=b[(l+l+r)/3]; while (i<=j) { while ((b[i].x*mid.y-b[i].y*mid.x)<0)i++; while ((b[j].x*mid.y-b[j].y*mid.x)>0)j--; if(i<=j)swap(b[i++],b[j--]); } if(i<r)Qsort(i,r); if(l<j)Qsort(l,j);}inline void make(long l){ for (long i=1;i<l;i++) { b[i].x = a[i].x - a[l].x; b[i].y = a[i].y - a[l].y; } for (long i=l+1;i<n+1;i++) { b[i-1].x = a[i].x-a[l].x; b[i-1].y = a[i].y-a[l].y; } #ifdef Debug for (long i=1;i<n;i++) printf("%lf%lf\n",b[i].x,b[i].y); #endif Qsort(1,n-1); for (long i=1;i<n;i++)/////////// { b[i+n-1] = b[i]; /////// } for (long i=1,j=2;i<n;i++) { pos c; c.x = -b[i].x; c.y = -b[i].y; while (c.x*b[j].y-c.y*b[j].x > 0.0) j++; if (j-i-1 >= 2) X+=((j-i-1)*(j-i-2))>>1; }}inline long long C(long i,long j){ if (c[i][j]) return c[i][j]; if (i < j) return 0; if (j == 0 || i == j) return 1; return c[i][j] = C(i-1,j)+C(i-1,j-1);}inline void solve(){ for (long i=1;i<n+1;i++) make(i); long long ans = 2*C(n,4)+X-(long long)(n)*C(n-1,3); printf("%lf",double(ans)/double(C(n,3))+3.0);}inline int getint(){ int res = 0; char tmp; bool sgn = 1; do tmp = getchar(); while (!isdigit(tmp) && tmp != '-'); if (tmp == '-') { sgn = 0; tmp = getchar(); } do res = (res << 1) + (res << 3) + tmp - '0'; while (isdigit(tmp = getchar())); return sgn ? res : -res;}int main(){ freopen("signaling.in","r",stdin); freopen("signaling.out","w",stdout); scanf("%ld",&n); for (long i=1;i<n+1;i++) { scanf("%lf%lf",&a[i].x,&a[i].y); } solve(); return 0;}
- 【计算几何】信号覆盖
- ☆【计算几何】信号覆盖
- [BZOJ 1913][APIO 2011]信号覆盖(计算几何)
- 【BZOJ2823】【AHOI2012】信号塔 最小圆覆盖 计算几何
- [BZOJ1913][Apio2010]signaling 信号覆盖(计算几何+组合数学)
- [BZOJ 1913][Apio2010]signaling 信号覆盖:计算几何
- 雷达覆盖_ssl1232_计算几何
- [计算几何笔记3]最小圆覆盖
- NYOJ squares(计算几何+区间覆盖)
- hdu3007Buried memory 最小圆覆盖 计算几何
- 雷达覆盖 ssl 1232 计算几何
- zoj 雷达覆盖(计算几何 向量)
- hdu-3007(计算几何+最小覆盖圆)
- HDU 3932(计算几何+最小圆覆盖)
- HDU 4720(计算几何+最小圆覆盖)
- bzoj 2823(计算几何+最小覆盖圆)
- BZOJ 2823 AHOI2012 信号塔 计算几何
- HDU4606 Occupy Cities 计算几何+最小路径覆盖
- 用心做软件—细节决定成败
- dwr
- Android之Graphics 简单绘制几何图形
- i2c_msg一些标志的解释
- ubuntu 删除unity
- 【计算几何】信号覆盖
- 将Asp.netMVC3网站通过iis6.0发布到window server 2003中
- android后台进程
- 安卓源码
- Magento安装流程概述
- ios5 目录1-15
- java环境变量配置
- 【资源推荐】Computer Vision 引文列表
- 用 prototype 定义自己的方法