Google Code Jam 2015 Round 1A C large

        把这个题专门写出来是因为我比赛时没做,并且学会了新的姿势。做法是枚举每个点i,以点i为中心,对其余点进行极角排序。注意atan2(double,double)这个函数的用法。为了使得点i在凸包上,极角排序后必须存在相邻点的极角差大于等于Pi(中间如果出现了点,需要删去)。因为atan的值域在-Pi和Pi之间,我们需要处理越过y轴负方向的情况方法是将atan小于0的值加上2*Pi。

        下面的代码是参考cgy4ever写的。没有优化跑得比较慢。。

#include <bits/stdc++.h>      
using namespace std;  

#define ll long long

const double eps = 1e-8;

struct Point{
	ll x,y;
	Point(ll x,ll y):x(x),y(y){
	}
	Point(){
	}
}pts[3010];

double ang[6010];

struct Vector{
	ll x,y;
	Vector(ll x,ll y):x(x),y(y){
	}
	Vector(){
	}
	Vector(Point A,Point B){
		x=B.x-A.x;
		y=B.y-A.y;
	}
};

ll Cross(Vector A,Vector B){
	return A.x*B.y - A.y*B.x;
}

int main(){	
	freopen("C-large-practice.in","r",stdin);
	freopen("C-large-practice.out","w",stdout);
	int t;
	cin>>t;
	int cas=0;
	while(t--){
		cas++;
		int n;
		cin>>n;
		
		for(int i=1;i<=n;i++){
			cin>>pts[i].x>>pts[i].y;
		}
		printf("Case #%d:\n",cas);
		
		for(int i=1;i<=n;i++){
			int ans=max(0,n-3);
			int pos=0;
			for(int j=1;j<=n;j++){
				if(i==j)continue;
				double d = atan2( pts[j].y-pts[i].y , pts[j].x-pts[i].x );
				ang[pos++]=d;
				ang[pos++]=d+2*M_PI;
			}
			sort(ang,ang+pos);
			
			bool flag=1;
			
			for(int j=0;j<n-1;j++){
				int k=j+1;
				while(ang[k]-ang[j]<M_PI-eps&&k<pos-1){
					k++;
				}
				if(ang[k]-ang[j]>M_PI-eps){
					ans=min(ans,k-j-1);
					flag=0;
				}
			}
			if(flag)ans=0;
			cout<<ans<<endl;
		}
	}
	return 0;
}


你可能感兴趣的:(code,Google,Jam,极角排序)