2016.08.07计算几何总结测试day2
2016-08-09 08:54
148 查看
T1 bzoj: [Usaco2010 OPen]Triangle Counting 数三角形
看到这个题n那么大, 于是想到极角排序搞一搞,然而排完序后立马懵逼,完全不知道接下来应该怎么写。。。。
盯了好久题目给的图后全无思路于是手绘图,然后我就发现了秘密。。。。
极角排序后,如果两个点能与另外的某一个点构成黄金三角形,那么那个点必然在这两个点与原点连线的延长线所夹的区间内。
又因为有极角排序,点a[1],a[2]能构成的三角形,换成点a[1],a[3]肯定也可以构成,因为它们的区间一定是包含关系。
于是我们搞出所有a[i],a[i-1]区间内的答案,计算对答案的贡献即可。
正着有i-1个区间包含它,反着有n-i个区间包含它,然后搞一搞就好了。。。
细节什么的参见代码,反正感觉我代码是写丑了,我还算出了j搞了两遍for循环,看他们代码一个个巨短。。。。理应一遍就应该可以了吧。。。。
T3
看到这个题n那么大, 于是想到极角排序搞一搞,然而排完序后立马懵逼,完全不知道接下来应该怎么写。。。。
盯了好久题目给的图后全无思路于是手绘图,然后我就发现了秘密。。。。
极角排序后,如果两个点能与另外的某一个点构成黄金三角形,那么那个点必然在这两个点与原点连线的延长线所夹的区间内。
又因为有极角排序,点a[1],a[2]能构成的三角形,换成点a[1],a[3]肯定也可以构成,因为它们的区间一定是包含关系。
于是我们搞出所有a[i],a[i-1]区间内的答案,计算对答案的贡献即可。
正着有i-1个区间包含它,反着有n-i个区间包含它,然后搞一搞就好了。。。
细节什么的参见代码,反正感觉我代码是写丑了,我还算出了j搞了两遍for循环,看他们代码一个个巨短。。。。理应一遍就应该可以了吧。。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define maxn 100010 #define inf 2000000 #define double long double const double eps=1e-9; int n,m; struct point{ double x,y,r; }a[maxn],b[maxn],O; double sqr(double x){return x*x;} double dis(point a,point b){return sqr(a.x-b.x)+sqr(a.y-b.y);} void getcircle(int i,int j){ O.r=dis(b[i],b[j])/4; O.x=(b[i].x+b[j].x)/2; O.y=(b[i].y+b[j].y)/2; } void getcircle(int i,int j,int k){ double a,c,d,e,f,g; a=2*(b[i].x-b[j].x); g=2*(b[i].y-b[j].y); c=sqr(b[i].x)-sqr(b[j].x)+sqr(b[i].y)-sqr(b[j].y); d=2*(b[i].x-b[k].x); e=2*(b[i].y-b[k].y); f=sqr(b[i].x)-sqr(b[k].x)+sqr(b[i].y)-sqr(b[k].y); O.x=(c*e-g*f)/(a*e-g*d); O.y=(c*d-a*f)/(g*d-a*e); O.r=dis(O,b[i]); } bool incircle(int i){ return dis(b[i],O)-O.r<=eps; } bool judgecircle(int l,int r,double limit){ // if (l==r) return 1; int cnt=0; for (int i=l;i<=r;i++) b[++cnt]=a[i]; random_shuffle(b+1,b+cnt+1); getcircle(1,2); if (O.r>sqr(limit)+eps) return 0; for (int i=3;i<=cnt;i++) if (!incircle(i)){ getcircle(1,i); if (O.r>sqr(limit)+eps) return 0; for (int j=2;j<i;j++) if (!incircle(j)){ getcircle(i,j); if (O.r>sqr(limit)+eps) return 0; for (int k=1;k<j;k++) if (!incircle(k)){ getcircle(i,j,k); if (O.r>sqr(limit)+eps) return 0; } } } return 1; } bool check(double limit){ int pos=0,num=0; for (int i=1;i<=n;i=pos+1){ int len=1; while (i+(len<<1)-1<=n && judgecircle(i,i+(len<<1)-1,limit)) len<<=1; int l=i+len-1,r=min(i+(len*2)-1,n); while (l<r){ int mid=(l+r)>>1; if (judgecircle(i,mid+1,limit)) l=mid+1; else r=mid; } pos=r,num++; if (num>m) return 0; } return 1; } int main(){ // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%Lf%Lf",&a[i].x,&a[i].y); double l=0,r=inf; while (l+1e-7<=r){ double mid=(l+r)/2; if (check(mid)) r=mid; else l=mid; } printf("%.6Lf\n",l); return 0; }
T3
相关文章推荐
- 2016.08.06计算几何总结测试day1
- 逻辑思维能力测试题归纳总结之计算题逻辑思维能力测试题归纳总结之计算题
- 计算几何收尾总结
- ACM 计算几何知识点总结 详解
- 创建一个几何类型类,其中有计算面积getArea()和周长getPerimeter()抽象方法,然后通过它派生出三角形类、圆形类、矩形类,并通过测试类进行测试
- 计算几何模板总结(二)
- [计算几何]计算几何_总结及资料
- 2017.7.24 机房测试(计算几何,花花的聚会,文本编辑器)
- 我的计算几何 总结
- 计算几何常用算法总结
- 【总结】计算几何模板
- 计算几何的中途总结
- 计算几何总结
- 计算几何总结
- 计算几何总结
- 二分+叉积 apio2011 陈可卿 计算几何的一道简单题 poj2318 兼集训总结
- 【计算几何】面积类题目总结
- 计算几何题目总结
- 计算几何总结
- 计算几何总结