2
思路:直接枚举所有墙的端点与宝物的位置作为一条线段(墙的端点与边界重合), 求出与之相交的最少线段数。就是答案
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int N = 35; const int INF = 0xffffff; const double eps = 1e-8; struct POINT { double x, y; }; struct LINE { POINT a, b; } l[N]; int n; double cross(POINT a, POINT b, POINT c)///根据正负判断三点是顺时针还是逆时针 { return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); } int Judge(POINT X, POINT Y) { int ans = 0; for(int i = 0; i < n; i ++) { if(cross(X, l[i].a, l[i].b) * cross(Y, l[i].a, l[i].b) < -eps)///判断两条线是否相交,即点X点Y在线l[i]的两侧,一个顺时针,一个逆时针,相乘小于0即在正方形区域一定相交 ans ++; } return ans; } int main() { int T; scanf("%d", &T); while(T --) { scanf("%d", &n); if(n == 0) { puts("1"); continue; } for(int i = 0; i < n; i ++) { scanf("%lf %lf %lf %lf", &l[i].a.x, &l[i].a.y, &l[i].b.x, &l[i].b.y); } POINT d; scanf("%lf %lf", &d.x, &d.y); int ans = INF; for(int i = 0; i < n; i++)///枚举求墙的端点与宝藏构成的线与其它线相交的最少次数 { ans = min(Judge(l[i].a, d), ans); ans = min(Judge(l[i].b, d), ans); } printf("%d\n", ans + 1);///加1是边界的墙 } return 0; }