UVa 11529 Strange Tax Calculation(极角排序)

来源:互联网 发布:java bug管理系统 编辑:程序博客网 时间:2024/05/16 18:48

问题可以这样求解:对于每个点求出它在多少个三角形之中,把这些数做和,就是所有三角形包含点的总数,除以三角形数就是答案。

问题就是对于每个点如何求出它在多少个三角形之中。

设该点为k,反向求有多少个三角形不包含它。方法是把其余点关于这个点k做极角排序,依次枚举每一个点i,把它当作三角形的一点,假设点j是最后一个和点i的夹角在pi以内的,那么在i+1和j之间这些点中任选2个点和i组成三角形,都不包括k。在枚举i时,求点j位置可以根据前一个i递推,也就是把前一次的点数减1,再继续往下边加边判断。时间复杂度是O(n),总体就是O(n^2)。

极角排序用atan2(y,x)函数就可以了,对这个向量返回到x轴正方向的夹角。对精度有损失,追求精度可以用象限+叉积排序。


代码:

////  main.cpp//  11529 Strange Tax Calculation////  Created by Baoli1100 on 15/2/15.//  Copyright (c) 2015年 Baoli1100. All rights reserved.//#include <iostream>using namespace std;#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define pi acos(-1.0)#define LL long longdouble k[2410];int N;double x[1210];double y[1210];LL solve(int n){    int cnt=0;    for(int i=0;i<N;i++){        if(i==n) continue;        k[cnt++]=atan2(y[i]-y[n],x[i]-x[n]);        k[cnt++]=atan2(y[i]-y[n],x[i]-x[n])+2*pi;    }    sort(k,k+cnt);    LL res=0;    int pos=0;    LL num=1;    for(int i=0;i<N-1;i++){        num--;        while(k[pos]<k[i]+pi){            num++;            pos++;        }        res+=(num-1)*(num-2)/2;        //cout<<(num-1)*(num-2)/2<<endl;    }    LL tot=(N-1)*(N-2)*(N-3)/6;    return tot-res;}int main(){    int kase=1;    while(~scanf("%d",&N)){        if(N==0) break;        for(int i=0;i<N;i++){            scanf("%lf%lf",&x[i],&y[i]);        }        LL tot=0;        for(int i=0;i<N;i++){            tot+=solve(i);        }        double res=tot*1.0/(N*(N-1)*(N-2)/6);        printf("City %d: %.2f\n",kase++,res);    }    return 0;}


UVa 11529 Strange Tax Calculation(极角排序)
0 0