PKU
1066 是一道感覺(jué)很好的題,用同側(cè)異側(cè)(位置)來(lái)表示的話思路會(huì)很清晰。
首先要從起點(diǎn)到終點(diǎn)穿過(guò)一道墻,等價(jià)于起點(diǎn)和終點(diǎn)在墻的異側(cè),這樣就清楚的表示了穿過(guò)一道墻的充要條件。
接下來(lái)也變得簡(jiǎn)單,就是枚舉終點(diǎn),終點(diǎn)顯然在正方形的邊上。很快能發(fā)現(xiàn)他們是一塊一塊的。緊鄰的交點(diǎn)(墻和正方形所交的點(diǎn))所構(gòu)成的線段上的點(diǎn)相對(duì)墻的位置是同側(cè)。因?yàn)樗麄儧](méi)有被任何墻分割開(kāi)。也就不可能異側(cè)。
這樣只要分塊枚舉,一塊枚舉只需一個(gè)點(diǎn)。

1 #include<iostream>
2 #include<cmath>
3 #include<algorithm>
4 using namespace std;
5 double const EPS = 1e-8;
6 const int INF = 1<<30;
7
8 int dcmp(double x){return x < -EPS ? -1 : x > EPS;}
9
10 struct Point{
11 double x,y;
12 Point(){}
13 Point(double a, double b):x(a), y(b){}
14 bool operator<(Point a){return atan2(y - 50, x - 50) < atan2(a.y - 50, a.x - 50); }
15 };
16
17 struct Line{Point a, b;};
18
19 Point P[128], s, t;
20 Line L[36];
21 int n, cnt, best;
22
23 double xmult(Point p1, Point p2 , Point p0)
24 {
25 return (p1.x - p0.x)*(p2.y - p0.y)-(p2.x - p0.x)*(p1.y - p0.y);
26 }
27 bool same_side(Point p1, Point p2, Line L)
28 {
29 return dcmp(xmult(L.b, p1, L.a) * xmult(L.b, p2, L.a)) >= 0;
30 }
31
32 int main()
33 {
34 int i, j, ans;
35 best = INF; cnt = 0;
36 P[cnt++] = Point(0, 0);
37 P[cnt++] = Point(100, 0);
38 P[cnt++] = Point(0, 100);
39 P[cnt++] = Point(100, 100);
40
41 cin >> n;
42 for(i = 0; i < n; i++)
43 {
44 cin>> L[i].a.x >> L[i].a.y >> L[i].b.x >> L[i].b.y;
45 P[cnt++] = L[i].a;
46 P[cnt++] = L[i].b;
47 }
48 cin>> s.x >> s.y;
49
50 sort(P, P+cnt);
51
52 for(i = 0; i < cnt; i++ )
53 {
54 ans = 0;
55 t = Point( (P[i].x + P[(i+1)%cnt].x)/2, (P[i].y + P[(i+1)%cnt].y)/2 );
56 for(j = 0; j < n; j++)
57 if(!same_side(s, t, L[j]))ans++;
58 if(ans < best) best = ans;
59 }
60
61 printf("Number of doors = %d\n", best+1);
62 }
posted on 2009-07-24 16:20
wangzhihao 閱讀(586)
評(píng)論(5) 編輯 收藏 引用 所屬分類:
geometry