[poj 1066][洛谷 UVA754] Treasure Hunt {判断两条线段是否相交}

题目

https://www.luogu.org/problemnew/show/UVA754
http://poj.org/problem?id=1066


解题思路

莫名其妙莫名其妙莫名其妙
CE了,求助!!!
CE了,求助!!!
CE了,求助!!!

我们可以通俗地理解题意为:
在边界任取点连接到目标点,问与多少的边相交。

判断两条线段是否相交(Cproduct为叉积)的条件:
(Cproduct(b1,b2,c1,c2,a1,a2)*Cproduct(b1,b2,d1,d2,a1,a2)<0&&Cproduct(d1,d2,b1,b2,c1,c2)*Cproduct(d1,d2,a1,a2,c1,c2)<0)


代码

#include
#define db double 
using namespace std; 
const int maxn=50; 
const int Inf=0x3f3f3f3f; 
const db Err=1e-8; 
inline int minn(int x,int y){return x<y?x:y;} 
int T,n; 
struct Vec{
    db x,y; db operator * (const Vec& oth)const {return x*oth.y-y*oth.x;}
};
struct Point{
    db x,y; Vec operator - (const Point& oth)const {return (Vec){x-oth.x,y-oth.y};}
}a[maxn],b[maxn],P;
int Solve(Point A,Point B){
    int ret=0; Vec AB=B-A; 
    for (int i=1;i<=n;++i) {
        Vec AC=a[i]-A,AD=b[i]-A,CD=b[i]-a[i],CB=B-a[i]; 
        if ((AB*AC)*(AB*AD)<-Err&&(CD*AC)*(CD*CB)>Err) ret++; 
    }
    return ret; 
}
int main(){
    scanf("%d",&T); 
    while (T--){
    scanf("%d",&n); int ans=Inf; 
    for (int i=1;i<=n;++i) scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&b[i].x,&b[i].y); 
    scanf("%lf%lf",&P.x,&P.y); 
    for (int i=1;i<=n;++i) ans=minn(ans,Solve(a[i],P)),ans=minn(ans,Solve(b[i],P)); 
    if (!n) ans=0; 
    printf("Number of doors = %d\n",ans+1); 
    if (T) printf("\n"); 
    }
    return 0; 
}

你可能感兴趣的:(计算几何)