//以下为原blog搬迁过来的内容
【题目大意】:给定一个矩形,和矩形内的墙,矩阵内有一个金矿,问你从矩阵外面进去直到金矿要至少穿越多少墙。
【解题思路】:一拿到题就没头没脑的枚举了所有边上的点,然后再直接就判线段相交。1A。结果反过来想,好像这种做法有点问题。看了discuss,有枚举终点的,有旋转的各种做法。以后再一一尝试。不过怎么感觉自己写的都不是正解。
【代码】:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <string> #include <cctype> #include <map> #include <iomanip> using namespace std; #define eps 1e-8 #define pi acos(-1.0) #define inf 1<<30 #define pb push_back #define lc(x) (x << 1) #define rc(x) (x << 1 | 1) #define lowbit(x) (x & (-x)) #define ll long long struct Point { double x, y; Point() {} Point(double a, double b) { x = a, y = b; } }point[1000]; struct Line { Point a, b; Line() {} Line(Point x, Point y) { a = x, b = y; } }line[1000]; inline int sig(double k) { return k < -eps ? -1 : k > eps; } inline double det(double x1, double y1, double x2, double y2) { return x1 * y2 - x2 * y1; } inline double xmult(Point o, Point a, Point b) { return det(a.x - o.x, a.y - o.y, b.x - o.x, b.y - o.y); } inline int intersect1(Point a, Point b, Point c, Point d) { double s1, s2, s3, s4; int d1 = sig(s1 = xmult(a, b, c)); int d2 = sig(s2 = xmult(a, b, d)); int d3 = sig(s3 = xmult(c, d, a)); int d4 = sig(s4 = xmult(c, d, b)); if ((d1^d2) == -2 && (d3^d4) == -2) { return 1; } return 0; } inline int intersect(Line u, Line v) { return intersect1(u.a, u.b, v.a, v.b); } int main() { int n; double p,q; scanf("%d",&n); for (int i=1; i<=n; i++) { scanf("%lf%lf",&p,&q); point[i*2-1]=Point(p,q); scanf("%lf%lf",&p,&q); point[i*2]=Point(p,q); line[i]=Line(point[2*i-1],point[2*i]); } scanf("%lf%lf",&p,&q); Point goal; goal=Point(p,q); int cnt,minn; minn=1<<30; for (int i=0; i<=2*n; i++) { cnt=1; for (int j=1; j<=n; j++) { Line tmp; tmp=Line(point[i],goal); int k; k=intersect(tmp,line[j]); if (k==1) cnt++; } if (cnt<=minn) minn=cnt; } printf("Number of doors = "); printf("%d\n",minn); return 0; }