题意:
给n条线段和初始点,求初始点发出的射线最多能穿过多少条线段(有交点就算穿过)。
分析:
枚举线段端点,判断线段是否规范相交,需要严密的模板。
代码:
//poj 4048 //sep9 #include <iostream> using namespace std; typedef long long ll; const ll maxN=2000; const ll maxL=40028; struct P { ll x,y; }a[maxN],b[maxN],p; ll tx,ty; int n; ll det(P a,P b,P c) { ll x1=b.x-a.x; ll y1=b.y-a.y; ll x2=c.x-a.x; ll y2=c.y-a.y; return x1*y2-x2*y1; } int get_sign(ll x) { if(x==0) return 0; return x>0?1:-1; } ll mymax(ll a,ll b) { return a>b?a:b; } ll mymin(ll a,ll b) { return a>b?b:a; } int between(P mid,P a,P b) { return mid.x<=max(a.x,b.x)&&mid.y<=max(a.y,b.y)&&mid.x>=min(a.x,b.x)&&mid.y>=min(a.y,b.y); } bool crossed(P a,P b,P c,P d) { int d1,d2,d3,d4; d1=get_sign(det(a,b,c)); d2=get_sign(det(a,b,d)); d3=get_sign(det(c,d,a)); d4=get_sign(det(c,d,b)); if((d1^d2)==-2&&(d3^d4)==-2) return true; if((d1==0&&between(c,a,b))|| (d2==0&&between(d,a,b))|| (d3==0&&between(a,c,d))|| (d4==0&&between(b,c,d))) return true; return false; } int process(P dir) { int cnt=0; dir.x=p.x+(dir.x-p.x)*10000; dir.y=p.y+(dir.y-p.y)*10000; if(dir.x==p.x&&dir.y==p.y) return 0; for(int i=1;i<=n;++i) if(crossed(p,dir,a[i],b[i])) ++cnt; return cnt; } int main() { int i,cases; scanf("%d",&cases); while(cases--){ scanf("%d",&n); for(i=1;i<=n;++i) scanf("%lld%lld%lld%lld",&a[i].x,&a[i].y,&b[i].x,&b[i].y); scanf("%lld%lld",&p.x,&p.y); int ans=0; for(i=1;i<=n;++i){ ans=max(ans,process(a[i])); ans=max(ans,process(b[i])); } printf("%d\n",ans); } return 0; }
poj 4048 Chinese Repeating Crossbow 线段规范相交的判断
原文地址:http://blog.csdn.net/sepnine/article/details/44781057