题意:
有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; }