poj 1066 Treasure Hunt
这题只要判断边上的中点与线段相交的交点就可以了,求出最小的交点数;
我们知道区域A的任何一点到线段a上的任何一点,要通过上面的3条线段,那么我直接连接区域A的点与线段a的点,经过的一定是3条直线,并且也是3个焦点;
因此,该题我们就只要判断交点的个数就可以了;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
View Code #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> using namespace std; class Point { public: double x,y; }p[224],point; class Line { public: Point A,B; }line[224],L[224]; int dcmp( double x ) { if( fabs( x ) < 1.0e-8 ) return 0; if( x < 0 ) return -1; return 1; } bool cmp( Point a, Point b ) { if( dcmp(a.x - b.x) ==0 ) return a.y < b.y; return a.x < b.x; } void Get_center( int n ) { for( int i = 0 ; i < n ; i++ ) { p[i].x = ( L[i].A.x + L[i].B.x )/2.0; p[i].y = ( L[i].A.y + L[i].B.y )/2.0; } } double multi( Point p1 , Point p2 , Point p ) { return ( p1.x - p.x )*( p2.y - p.y ) - ( p2.x - p.x )*( p1.y - p.y ); } int segment( Point p1 , Point p2 ,int n ) { int cnt = 0; for( int i = 0; i < n ; i ++ ) { int d1 = dcmp( multi(line[i].A , line[i].B, p2) ); int d2 = dcmp( multi(line[i].A , line[i].B, p1) ); if( d1 * d2 < 0 ) cnt++; } return cnt; } int Min( int a , int b ) { return a < b ?a : b; } int Solve( int n ,int m ) { int ans = 0x7fffffff; for( int i = 0 ; i < n ; i++ ) { ans = Min( segment( point , p[i] ,m ) ,ans ); } return ans + 1; } int main( ) { int n ; while( scanf( "%d",&n )==1 ) { int cnt = 4; p[0].x = 0 ; p[0].y = 0; p[1].x = 0 ; p[1].y =100; p[2].x = 100 ;p[2].y = 0; p[3].x = 100 ;p[2].y =100; for( int i = 0 ; i < n ; i ++ ) { scanf( "%lf %lf",&line[i].A.x,&line[i].A.y ); scanf( "%lf %lf",&line[i].B.x,&line[i].B.y ); p[cnt++] = line[i].A; p[cnt++] = line[i].B; } scanf( "%lf %lf",&point.x , &point.y ); printf("Number of doors = %d\n",Solve( cnt , n )); } //system( "pause" ); return 0; }