POJ 1066 判断线段相交

题意:有个考古队进金字塔里盗墓,大小100*100,样图是一个俯视图,给了财宝坐标,又给了各个墙。题目规定考古队在每面墙的中点处开一个洞,这样就避免了两墙交点的情况,求最小的凿墙数目。

很明显,枚举连接四面两个墙之间中点与宝藏的线段,求出这种线段与墓里墙相交的最小值。其实可以不用枚举中点,直接用墙的端点与宝藏相连的线段就行,细想一想可以想明白。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef double PointType;
struct point
{
    PointType x,y;
};
PointType Direction(point pi,point pj,point pk) //判断向量PiPj在向量PiPk的顺逆时针方向 +顺-逆0共线
{
    return (pj.x-pi.x)*(pk.y-pi.y)-(pk.x-pi.x)*(pj.y-pi.y);
}
bool On_Segment(point pi,point pj,point pk)
{
    if(pk.x>=min(pi.x,pj.x)&&pk.x<=max(pi.x,pj.x)&&pk.y>=min(pi.y,pj.y)&&pk.y<=max(pi.y,pj.y))
        return 1;
    return 0;
}
bool Segment_Intersect(point p1,point p2,point p3,point p4)
{
    PointType d1=Direction(p3,p4,p1),d2=Direction(p3,p4,p2),d3=Direction(p1,p2,p3),d4=Direction(p1,p2,p4);
    if(((d1>0&&d2<0)||(d1<0&&d2>0))&&((d3>0&&d4<0)||(d3<0&&d4>0)))
        return 1;
    if(d1==0&&On_Segment(p3,p4,p1))
        return 1;
    if(d2==0&&On_Segment(p3,p4,p2))
        return 1;
    if(d3==0&&On_Segment(p1,p2,p3))
        return 1;
    if(d4==0&&On_Segment(p1,p2,p4))
        return 1;
    return 0;
}
double x1[10000],x2[10000],y1[10000],y2[10000];
int w,nx1,nx2,ny1,ny2;
point data[10000][2];
void zx(double m,double n)
{
    if(m==0)
    {
        y1[ny1++]=n;
        return;
    }
    if(m==100)
    {
        y2[ny2++]=n;
        return;
    }
    if(n==0)
    {
        x1[nx1++]=m;
        return;
    }
    if(n==100)
    {
        x2[nx2++]=m;
        return;
    }
}
int main()
{
    while(~scanf("%d",&w))
    {
        nx1=nx2=ny1=ny2=0;
        double m,n;
        for(int i=0; i<w; i++)
        {
            scanf("%lf%lf",&m,&n);
            zx(m,n),data[i][0].x=m,data[i][0].y=n;
            scanf("%lf%lf",&m,&n);
            zx(m,n),data[i][1].x=m,data[i][1].y=n;
        }
        point temp,t;
        scanf("%lf%lf",&t.x,&t.y);
        if(w==0)
        {
            puts("Number of doors = 1");
            continue;
        }
        int sum=9999999;
        for(int i=0; i<ny1; i++)
        {
            temp.x=0,temp.y=y1[i];
            int num=1;
            for(int j=0; j<w; j++)
                if(Segment_Intersect(data[j][0],data[j][1],temp,t)&&(data[j][0].y!=temp.y&&data[j][1].y!=temp.y))
                    num++;
            sum=min(sum,num);
        }
        for(int i=0; i<ny2; i++)
        {
            temp.x=100,temp.y=y2[i];
            int num=1;
            for(int j=0; j<w; j++)
                if(Segment_Intersect(data[j][0],data[j][1],temp,t)&&(data[j][0].y!=temp.y&&data[j][1].y!=temp.y))
                    num++;
            sum=min(sum,num);
        }
        for(int i=0; i<nx1; i++)
        {
            temp.x=x1[i],temp.y=0;
            int num=1;
            for(int j=0; j<w; j++)
                if(Segment_Intersect(data[j][0],data[j][1],temp,t)&&(data[j][0].x!=temp.x&&data[j][1].x!=temp.x))
                    num++;
            sum=min(sum,num);
        }
        for(int i=0; i<nx2; i++)
        {
            temp.x=x2[i],temp.y=100;
            int num=1;
            for(int j=0; j<w; j++)
                if(Segment_Intersect(data[j][0],data[j][1],temp,t)&&(data[j][0].x!=temp.x&&data[j][1].x!=temp.x))
                    num++;
            sum=min(sum,num);
        }
        printf("Number of doors = %d\n",sum);
    }
    return 0;
}
时间: 2024-09-23 17:57:37

POJ 1066 判断线段相交的相关文章

POJ 2653 暴力判断线段相交

题意是按照输入的先后顺序放木棍,然后输出最上层的木棍,何为最上层,就是木棍上方没有木棍和它相交就行. 这题坑爹啊,一直TLE后来才发现最上层木棍不是底下的木棍数最多而是只要上方没有木棍就行.所以只需要开一个标记数组从前往后如果后面有与它相交的那么这个木棍肯定不是最上层的,知道这些再知道线段相交的模板就可以A了. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm>

POJ 1410 判断线段相交点在多边形内外

题意:判断一线段与矩形是否相交.需要注意的是输入可能不是按照左上右下的顺序,如果线段两个端点都在举行内的话也算相交. 这题分为判断线段与4边是否有交点,如果没有判断两点是否在矩形内就可以了.我用的方法是射线法. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef double PointType; str

POJ 3449 判断多边形相交

题意:给你多边形 让你判断每个多边形分别有几个多边形与它相交. 这题的输入输出恶心,另外给出正方形对角点求出另两个点的公式 已知一正方形两对角顶点A.C的坐标分别是(ax, ay).(cx, xy): 求B.D坐标(bx, by).(dx, dy):           bx = (cx+ax+cy-ay)/2;           by = (cy+ay+ax-cx)/2;           dx = (cx+ax+ay-cy)/2;           dy = (cy+ay+cx-ax)

判断线段与多边形、多边形与多边形是否相交的算法(C#)

问题描述 判断线段与多边形.多边形与多边形是否相交(C#),包括线段.多边形包含在多边形内,线段与多边形某一条边重合的情况判断.求教各位大神!我有写一个判断线段与多边形的边时候相交的算法,但是貌似没有判断成功,请各位大神指导!谢谢!publicboolGetLineIntersection(GraphicGraphic,GraphicDrawPolygonGraphic){doubledistAB,theCos,theSin,newX,ABpos;doubleX=0;doubleY=0;Draw

C++判断矩形相交的方法_C 语言

本文实例讲述了C++判断矩形相交的方法.分享给大家供大家参考.具体如下: 已知2矩形原点和宽高,判断2矩形相交,相交矩形 相交判断原理: 假定矩形是用一对点表达的(minx, miny) (maxx, maxy),那么两个矩形     rect1{(minx1, miny1)(maxx1, maxy1)}     rect2{(minx2, miny2)(maxx2, maxy2)}  相交的结果一定是个矩形,构成这个相交矩形rect{(minx, miny) (maxx, maxy)}的点对坐

POJ 3304 判断直线与线段相交

题意:问存不存在一条直线,各个线段在直线上的投影有公共部分,也就是判断是否存在一条直线将所有线段都相交. 枚举所有端点构成的直线如果有一条直线相交所有线段那么就存在. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define eps 1e-8 typedef doub

POJ 1556 线段相交+最短路

题意:给出一个房间的俯视图 求从(0,5)到(10,5)的最短路径. 求出没有墙挡住的两点距离再用弗洛伊德求出0-sum的最短路径就可以.需要注意最短路可能经过某墙的端点,这时候不能判断条路径为非法. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef doub

POJ 2074 线段相交 视线问题

题意:给你一个代表房子的线段,代表路的线段,然后代表各种障碍物的线段.求出路上最长的区间,在区间中能看到完整的房子. 首先筛选出纵坐标在房子与路之间的,再根据视线完全能看到就行了. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef double PointType; struct point { Poi

POJ 2826 两线段关系求面积

题意:两个木板接雨,问你能解多少雨,也就是面积. 这题考虑几种情况:1,有线段平行x轴,接不到:2,两线段没交点,接不到:3,取两线段高的端点如果比两线段交点低也接不到:4,最不容易想到的,两木板在同侧并且上面的木板盖住了下面的木板也接不到.这四条单独判断然后求三角形面积就可以了. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cm