BZOJ1074 [SCOI2007]折纸origami
原文地址http://www.cnblogs.com/Christopher-Cao/p/5482575.html
这道题是计算几何的裸题。看起来折叠了几次要用什么东西来维护,实际上因为n<=8所以可以暴力统计。唯一有难度的东西是找出一个点的对称点(实际上也没有什么难度吧)
贴代码
1 #include<cstdio> 2 #include<cmath> 3 #include<vector> 4 using namespace std ; 5 6 const int MAXN = 10 ; 7 const int MAXM = 60 ; 8 const double eps = 1e-6 ; 9 int N , M ; 10 11 struct Point { 12 double x , y ; 13 Point ( const double x , const double y ) : 14 x ( x ) , y ( y ) {} ; 15 } ; 16 17 struct Vector { 18 double x , y ; 19 Vector ( const double x , const double y ) : 20 x ( x ) , y ( y ) {} ; 21 } ; 22 23 struct Line { 24 Point From , To ; 25 Line ( const double x1 , const double y1 , 26 const double x2 , const double y2 ) : 27 From ( x1 , y1 ) , To ( x2 , y2 ) {} ; 28 Vector toVector () const ; 29 } ; 30 31 Vector operator - ( const Point & First , const Point & Second ) { 32 return Vector ( First . x - Second . x , First . y - Second . y ) ; 33 } 34 35 Point operator - ( const Point & First , const Vector & Second ) { 36 return Point ( First . x - Second . x , First . y - Second . y ) ; 37 } 38 39 Vector operator * ( const double k , const Vector & Input ) { 40 return Vector ( k * Input . x , k * Input . y ) ; 41 } 42 43 Point operator + ( const Point & First , const Vector & Second ) { 44 return Point ( First . x + Second . x , First . y + Second . y ) ; 45 } 46 47 //上面是向量的定义和各种加减运算 48 double operator ^ ( const Vector & First , const Vector & Second ) { 49 return First . x * Second . y - First . y * Second . x ; 50 } 51 //叉积 52 double operator * ( const Vector & First , const Vector & Second ) { 53 return First . x * Second . x + First . y * Second . y ; 54 } 55 //内积 56 double abs ( const Vector & Input ) { 57 return sqrt ( Input . x * Input . x + Input . y * Input . y ) ; 58 } 59 //模 60 Vector Line :: toVector () const { return To - From ; } 61 62 vector < Line > Opts ; 63 64 Point reflect ( const Point o , const Line L ) { 65 const double dis = ( ( L . From - o ) ^ ( L . To - o ) ) / abs ( L . toVector () ) ; 66 const Vector Lp = 1.0 / abs ( L . toVector () ) * L . toVector () ; 67 return o + 2.0 * dis * Vector ( Lp . y , - Lp . x ) ; 68 } 69 70 int Query ( const Point o , const int T ) { 71 //printf ( "Dfs %.2lf %.2lf %d\n" , o . x , o . y , T ) ; 72 if ( T == -1 ) 73 return ( eps <= o . x && o . x <= 100.0 - eps ) && 74 ( eps <= o . y && o . y <= 100.0 - eps ) ; 75 //这个地方一开始的时候没有加eps所以wa了(良心样例) 76 const double CrossValue = 77 ( ( Opts [ T ] . From - o ) ^ ( Opts [ T ] . To - o ) ) ; 78 if ( CrossValue < - eps ) return 0 ; 79 if ( - eps <= CrossValue && CrossValue <= eps ) return 0 ; 80 //这个地方多了一行是因为一开始读题的时候以为边界上只算一次,后来没过样例才明白边界不算 81 return Query ( o , T - 1 ) + 82 Query ( reflect ( o , Opts [ T ] ) , T - 1 ) ; 83 } 84 85 int main () { 86 scanf ( "%d" , & N ) ; 87 for ( int i = 0 ; i < N ; ++ i ) { 88 double x1 , y1 , x2 , y2 ; 89 scanf ( "%lf%lf%lf%lf" , & x1 , & y1 , & x2 , & y2 ) ; 90 Opts . push_back ( Line ( x1 , y1 , x2 , y2 ) ) ; 91 } 92 scanf ( "%d" , & M ) ; 93 while ( M -- ) { 94 double x , y ; 95 scanf ( "%lf%lf" , & x , & y ) ; 96 printf ( "%d\n" , Query ( Point ( x , y ) , N - 1 ) ) ; 97 } 98 return 0 ; 99 }