如果不是做过HDU的3629,估计这题会卡很多。。
HDU的3629是求给你N个点,问你能组成多少个凸的四边形。
当时的做法就是,求出有多少个凹的四边形,然后拿C(n,4)减去凹的数目即可。
而这个题是求所有三角形区域中包含的内点的个数,其实想一想,不就是求凹的四边形有多少个么。
然后拿那个题的代码改改,就过了,而且居然还排第一了。。。哈哈。。
不过当初做HDU的那个题可是费了不少事 = =。。
对每个点进行极角排序,然后枚举顶点和其中一个点,然后扫描线旋转,假设原点为X,扫描线计算的就是以点X为凸顶点的四边形的个数,那么用C(n-1,3)减去这些个数就是以X为凹顶点的四边形的个数。
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
const int MAX = 2410;
const double pi = acos(-1.0);
struct point {double x,y;};
point p[MAX];
double a[MAX];
long long C2(int n)
{
return n*(n-1ll)/2;
}
long long C3(int n)
{
return n*1ll*(n-1)*(n-2)/6;
}
long long solve(int n)
{
long long ans = 0ll,t3 = C3(n-1);
for(int i=0; i<n; i++)
{
if( i != 0 )
swap(p[0],p[i]);
for(int k=1; k<n; k++)
a[k] = atan2(p[k].y - p[0].y,p[k].x - p[0].x);
sort(a+1,a+n);
for(int k=1; k<n; k++)
a[n+k-1] = a[k] + 2*pi;
int t = 1;
long long tt = 0ll;
for(int k=1; k<n; k++)
{
while( a[t] < a[k] + pi )
t++;
tt += C2(t-k-1);
}
ans += (t3 - tt);
}
return ans;
}
int main()
{
int ncases,n;
int ind = 1;
while( ~scanf("%d",&n) && n )
{
for(int i=0; i<n; i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
long long ans = solve(n);
double p = ans*1.0/C3(n);
printf("City %d: %.2lf\n",ind++, p);
}
return 0;
}