sicilyOJ 09广东省赛重现D A Carnival Game(计算几何)

题意:

有n个扇形,每个扇形给从外到里分为K个部分,并且每个扇形都不相交或者覆盖,扇形从外到里的部分分数为1,2,3...K

然后给一个圆,判断圆是不是在某个扇形中,并且不和扇形的弧和边相交。

如果圆在扇形某个部分,并且不和扇形相交,求出它所在部分的分数,如果不在扇形里面或者和扇形相交输出0.


思路:

对于某个圆,暴力枚举它是不是和扇形相交,或者圆心在扇形里面。

如果和扇形外面的边相交,就输出0

如果不和扇形的外面的边相交,并且圆心在扇形里面,就判断它是不是它旁边两条弧相交。

第一次交不知道精度还是哪里错了,wa了。。随便改改交上就AC... 也不知道哪里改对了。。



#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<stack>
using namespace std;

#define inf 0x3f3f3f3f
#define eps 1e-7
#define LL long long
#define ULL unsigned long long
#define MP make_pair
#define pb push_back
#define ls ( i << 1 )
#define rs ( ls | 1 )
#define md ( ( ll[i] + rr[i] ) >> 1 )
#define PI acos( -1.0 )
#define mxn 102200

  
int dcmp( double x ) {  
    if( fabs( x ) < eps )  
        return 0;  
    return x < 0 ? -1: 1;  
}  
  
  
struct point {  
    double x, y;  
    point( double x = 0, double y = 0 ): x( x ), y( y ) {}  
    point operator + ( const point &b ) const {  
        return point( x + b.x, y + b.y );  
    }  
    point operator - ( const point &b ) const {  
        return point( x - b.x, y - b.y );  
    }  
    point operator * ( const double &k ) const {  
        return point( x * k, y * k );  
    }  
    point operator / ( const double &k ) const {  
        return point( x / k, y / k );  
    }  
    bool operator < ( const point &b ) const {  
        if( dcmp( x - b.x ) != 0 )  
            return x < b.x;  
        return y < b.y;  
    }  
    bool operator == ( const point &b ) const {  
        return dcmp( x - b.x ) == 0 && dcmp( y - b.y ) == 0;  
    }  
    double len() {  
        return sqrt( x * x + y * y );  
    }  
};  

double cross( point A, point B ) {  
    return A.x * B.y - A.y * B.x;  
}  
double dot( point A, point B ) { 
    return A.x * B.x + A.y * B.y;  
} 
point Normal( point A ) {
    double L = A.len();  
    return point( - A.y / L, A.x / L );  
} 
double dis( point a, point b ) {
	return ( a - b ).len();
}
int n, m, K;
double DisToSeg( point P, point A, point B ) {  
    if( A == B )  
        return ( P - A ).len();  
    point v1 = B - A, v2 = P - A, v3 = P - B;  
    if( dcmp( dot( v1, v2 ) ) < 0 )  
        return v2.len();  
    if( dcmp( dot( v1, v3 ) ) > 0 )  
        return v3.len();  
    return fabs( cross( v1, v2 ) / v1.len() );  
} 
struct sect {
	point c, ll, rr;
	double r;
	double al, ar;
	sect() {}
	sect( point ll, point rr, double r ): ll( ll ), rr( rr ), r( r ) {
		point mid = ( ll + rr ) / 2;
		c = Normal( rr - mid ) * sqrt( r * r - ( rr - mid ) .len() * ( rr - mid ) .len() ) + mid;
		al = atan2( ( ll - c ).y, ( ll - c ) .x );
		ar = atan2( ( rr - c ).y, ( rr - c ). x );
	};
	bool in( point a ) {
		if( dis( a, c ) > r )
			return 0;
		double tem = atan2( ( a - c ).y, ( a - c ).x );
		if( dcmp( ar - al ) >= 0 )
			return tem >= al && tem <= ar;
		if( ( dcmp( al - tem ) <= 0 ) || dcmp( tem - ar ) <= 0 ) 
			return 1;
		return 0;
	}
	bool inter( point a, double k ) {
		if( in( a ) )
			return 1;
		if( dcmp( DisToSeg( a, c, ll ) - k ) <= 0|| dcmp( DisToSeg( a, c, rr ) - k ) <= 0 )
			return 1;
		double tem = atan2( ( a - c ).y, ( a - c ).x );
		double D = dis( a, c );
		if( dcmp( al - ar ) <= 0 ) {
			if( tem >= al && tem <= ar ) 
				if( D <= k + r )
					return 1;
			return 0;
		}
		if( tem >= al || tem <= ar ) {
			if( D <= k + r )
				return 1;
			return 0;
		}
		return 0;
	}
	int get( point a, double r0 ) {
		if( dcmp( DisToSeg( a, c, ll ) - r0 ) <= 0 || dcmp( DisToSeg( a, c, rr ) - r0 ) <= 0 )
			return 0;
		double t = r / K;
		double di = dis( a, c );
		if( dcmp( di + r0 - r ) >= 0 )
			return 0;
		int z = di / t;
		if( z == K )
			return 0;
		if( dcmp( di - z * t - r0 ) <= 0 || dcmp( di + r0 - z * t - t ) >= 0)
			return 0;
		return K - z;
	}
}s[mxn];

void read() {
	scanf( "%d%d", &n, &K );
	double x2, y2, x3, y3, R;
	for( int i = 1; i <= n; ++i ) {
		scanf( "%lf%lf%lf%lf%lf", &x2, &y2, &x3, &y3, &R );
		s[i] = sect( point( x2, y2 ), point( x3, y3 ), R );
	}
};

void calc( double x, double y, double r ) {
	point p( x, y );
	for( int i = 1; i <= n; ++i ) {
		if( s[i].inter( p, r ) ) {
			if( !s[i].in( p ) ) {
				puts( "0" );
				return;
			}
			printf( "%d\n", s[i].get( p, r ) );
			return;
		}
	}
	printf( "0\n" );
}
int main() {
//	freopen( "tt.txt", "r", stdin );
	int cas;
	int kk = 1;
	scanf( "%d", &cas );
	while( cas-- ) {
		read();
		scanf( "%d", &m );
		printf( "Case %d:\n", kk++ );
		while( m-- ) {
			double x, y, r;
			scanf( "%lf%lf%lf", &x, &y, &r );
			calc( x, y, r );
		}
	}
	return 0;
}


你可能感兴趣的:(sicilyOJ 09广东省赛重现D A Carnival Game(计算几何))