1. 程式人生 > >【BZOJ】1913: [Apio2010]signaling 信號覆蓋(計算幾何+計數)

【BZOJ】1913: [Apio2010]signaling 信號覆蓋(計算幾何+計數)

AS %d poi problem apio2010 atan ext 分析 nbsp

題目

傳送門:QWQ

分析

人類智慧題,不會做。。。。。。

詳細題解1 詳細題解2

總體思路是考慮四邊形

討論凹四邊形凸四邊形,最後加一個單調性優化省掉個$ O(n) $

代碼

代碼感覺好短啊

//https://blog.csdn.net/regina8023/article/details/45556321
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1550;
const double PI=acos(-1
); struct Point{ double x,y; }p[maxn]; LL C(int n,int m){ LL ans=1; for (int i=1;i<=m;i++) ans=1LL*ans*(n-i+1); for (int i=2;i<=m;i++) ans/=i; return ans; } double a[2*maxn]; int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf(
"%lf%lf",&p[i].x,&p[i].y); } double anss=0; for(int i=1;i<=n;i++){ int tot=0; for(int j=1;j<=n;j++){ if(i==j) continue; a[++tot]=atan2(p[j].x-p[i].x,p[j].y-p[i].y); if (a[tot]<0) a[tot]+=PI*2; } sort(a
+1,a+n); for(int j=0;j<n;j++){ a[j+n]=a[j+1]+2*PI; } int now=1; LL ans=0; for(int j=1;j<n;j++){ while(now<n+n-2 && a[now+1]-a[j]<PI){ now++; } if(now-j>1)ans+=C(now-j,2); }//這裏計算的是凸四邊形 anss+=(double)(C(n-1,3)-ans);//凹四邊形 } anss=(double)(anss+2*(C(n,4)-anss))/C(n,3) + 3; printf("%.6lf\n",anss); return 0; }

【BZOJ】1913: [Apio2010]signaling 信號覆蓋(計算幾何+計數)