# BZOJ1074 [SCOI2007]折纸origami

 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 }

posted @ 2016-05-11 17:03  Chris_2  阅读(424)  评论(0编辑  收藏  举报