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 }

 

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