POJ 1066 Treasure Hunt【线段相交】

思路:枚举四边墙的门的中点,与终点连成一条线段,判断与其相交的线段的个数。最小的加一即为答案。

我是傻逼,一个数组越界调了两个小时。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
const int N=1000; 
const double eps=1e-8;
int sgn(double x){
    if(fabs(x)<eps)    return 0;
    if(x>0)    return 1;
    return -1;
}
struct point{
    double x,y;
    point(){}
    point(double x_,double y_){
        x=x_,y=y_;
    }
    point operator -(const point &b)const{
        return point(x-b.x,y-b.y);
    }
    double operator *(const point &b)const{
        return x*b.x+y*b.y;
    }
    double operator ^(const point &b)const{
        return x*b.y-y*b.x;
    }
}po[N];
struct line{
    point s,e;
    line(){}
    line(point s_,point e_){
        s=s_,e=e_;
    }
}li[N];
double cal(point p0,point p1,point p2){//叉积 
    return (p1-p0)^(p2-p0); 
}
int xj(line a,line b){//判断两线段是否相交 
    point A=a.s,B=a.e,C=b.s,D=b.e;
    return 
    max(A.x,B.x)>=min(C.x,D.x) &&
    max(C.x,D.x)>=min(A.x,B.x) &&
    max(A.y,B.y)>=min(C.y,D.y) &&
    max(C.y,D.y)>=min(A.y,B.y) &&
    sgn(cal(C,A,B))*sgn(cal(D,A,B))<=0 &&
    sgn(cal(A,C,D))*sgn(cal(B,C,D))<=0;
}
int p[111][111];
int main(){
    int n,i,j,js;
    double x1,y1,x2,y2;
    while(~scanf("%d",&n)){
        memset(p,0,sizeof(p));js=0;
        for(i=1;i<=n;i++){
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            p[(int)x1][(int)y1]=p[(int)x2][(int)y2]=1;
            li[i]=line(point(x1,y1),point(x2,y2));
        }
        scanf("%lf%lf",&x1,&y1);
        point P=point(x1,y1);
        p[0][0]=1;
        p[0][100]=1;
        p[100][100]=1;
        p[100][0]=1;
        int x0,y0;
        for(y0=0,i=1;i<=100;i++){
            if(p[0][i]){
                po[++js]=point(0,(i+y0)/2.0);
                y0=i;
            }
        }
        for(x0=0,i=1;i<=100;i++){
            if(p[i][100]){
                po[++js]=point((i+x0)/2.0,100);
                x0=i;
            }
        }
        for(y0=0,i=1;i<=100;i++){
            if(p[100][i]){
                po[++js]=point(100,(i+y0)/2.0);
                y0=i;
            }
        }
        for(x0=0,i=1;i<=100;i++){
            if(p[i][0]){
                po[++js]=point((i+x0)/2.0,0);
                x0=i;
            }
        }
        int ans=1000;
        for(i=1;i<=js;i++){
            line L=line(P,po[i]);
            int cnt=0;
            for(j=1;j<=n;j++){
                if(xj(L,li[j])){
                    cnt++;
                }
            }
            if(cnt<ans)    ans=cnt;
        }
        printf("Number of doors = %d
",ans+1);
    }
    return 0;
} 
原文地址:https://www.cnblogs.com/L-King/p/5735823.html