枚举所有墙的2n个端点与宝物的位置作为一条线段(墙的端点必定与边界重合), 求出与之相交的最少线段数(判断线段相交时用跨立实验的方法),+1即为结果。
#include<bits/stdc++.h> using namespace std; struct point { double x,y; point operator -(const point& rhs)const { point ret; ret.x=x-rhs.x; ret.y=y-rhs.y; return ret; } double operator *(const point& rhs)const//叉乘 { return x*rhs.y-y*rhs.x; } bool operator <(const point& rhs)const { return x<rhs.x||x==rhs.x&&y<rhs.y; } } la[105],lb[105],en; int n; bool ok(point a,point b,point c,point d) { return ((b-a)*(c-a))*((b-a)*(d-a))<0; } int cal(point A,point B) { int ret=0; for(int i=0; i<n; i++) if(ok(la[i],lb[i],A,B)) ret++; return ret; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); if(n<3) { puts("1"); //边界占一个 continue; } for(int i=0; i<n; i++) scanf("%lf%lf%lf%lf",&la[i].x,&la[i].y,&lb[i].x,&lb[i].y); scanf("%lf%lf",&en.x,&en.y); int ans=1000; for(int i=0; i<n; i++) { ans=min(ans,cal(en,la[i])); ans=min(ans,cal(en,lb[i])); } printf("%d\n",ans+1); } }
时间: 2024-10-07 16:14:37