POJ3335 POJ3130 [半平面交]

终于写出自己的半平面交模板了.......

加入交点的地方用了直线线段相交判定

两个题一样,只不过一个顺时针一个逆时针(给出一个多边形的两种方式啦),反正那个CutPolygon是切掉左面

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=105;
const double INF=1e5;
const double eps=1e-8;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘; c=getchar();}
    return x*f;
}

inline int sgn(double x){
    if(abs(x)<eps) return 0;
    else return x<0?-1:1;
}

struct Vector{
    double x,y;
    Vector(double a=0,double b=0):x(a),y(b){}
    bool operator <(const Vector &a)const{
        return sgn(x-a.x)<0||(sgn(x-a.x)==0&&sgn(y-a.y)<0);
    }
    void print(char c){printf("%c %lf %lf\n",c,x,y);}
};
typedef Vector Point;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
Vector operator *(Vector a,double b){return Vector(a.x*b,a.y*b);}
Vector operator /(Vector a,double b){return Vector(a.x/b,a.y/b);}
bool operator ==(Vector a,Vector b){return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;}
double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}
double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}

double Len(Vector a){return sqrt(Dot(a,a));}

double DisTL(Point p,Point a,Point b){
    Vector v1=b-a,v2=p-a;
    return abs(Cross(v1,v2)/Len(v1));
}
struct Line{
    Point s,t;
    Line(){}
    Line(Point a,Point b):s(a),t(b){}
};
bool isLSI(Line l1,Line l2){
    Vector v=l1.t-l1.s,u=l2.s-l1.s,w=l2.t-l1.s;
    return sgn(Cross(v,u))!=sgn(Cross(v,w));
}
Point LI(Line a,Line b){
    Vector v=a.s-b.s,v1=a.t-a.s,v2=b.t-b.s;
    double t=Cross(v2,v)/Cross(v1,v2);
    return a.s+v1*t;
}
void iniPolygon(Point p[],int &n,double inf){
    n=0;
    p[++n]=Point(-inf,-inf);
    p[++n]=Point(inf,-inf);
    p[++n]=Point(inf,inf);
    p[++n]=Point(-inf,inf);
}
Point t[N];int tn;
void CutPolygon(Point p[],int &n,Point a,Point b){//get the left of a->b
    memset(t,0,sizeof(t));tn=0;
    Point c,d,e;
    for(int i=1;i<=n;i++){
        c=p[i],d=p[i%n+1];
        if(sgn(Cross(b-a,c-a))>=0) t[++tn]=c;
        if(isLSI(Line(a,b),Line(c,d))){
            e=LI(Line(a,b),Line(c,d));//e.print(‘e‘);
            t[++tn]=e;
        }
    }
    n=tn;for(int i=1;i<=n;i++)p[i]=t[i];
}

int n,m;
Point p[N],q[N];
int main(int argc, const char * argv[]) {
    while(true){
        n=read();if(n==0) break;
        iniPolygon(q,m,INF);
        for(int i=1;i<=n;i++) p[i].x=read(),p[i].y=read();
        for(int i=1;i<=n;i++) CutPolygon(q,m,p[i],p[i%n+1]);//,printf("%d\n",m);
        if(m) puts("1");else puts("0");
    }
}
时间: 2024-10-09 15:11:53

POJ3335 POJ3130 [半平面交]的相关文章

poj3335 半平面交模版

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef double dd; #define N 200 struct P{ dd x,y; P(dd a=0,dd b=0){ x=a,y=b; } P operator+(P a){ return P(x+a.x,y+a.y); } P operator-(P

半平面交算法及简单应用

半平面:一条直线把二维平面分成两个平面. 半平面交:在二维几何平面上,给出若干个半平面,求它们的公共部分 半平面交的结果:1.凸多边形(后面会讲解到)2.无界,因为有可能若干半平面没有形成封闭3.直线,线段,点,空(属于特殊情况吧) 算法:1:根据上图可以知道,运用给出的多边形每相邻两点形成一条直线来切割原有多边形,如果多边形上的点i在有向直线的左边或者在直线上即保存起来,否则判断此点的前一个点i-1和后一个点i+1是否在此直线的左边或线上,在的话分别用点i和点i-1构成的直线与此时正在切割的直

POJ 1474 Video Surveillance 半平面交求多边形是否有核

裸的半平面交求多边形是否有核. 多边形的核: 在多边形核上的点可以看到多边形的所有顶点,凸多边形的核显然就是多边形本身. 多边形的核是一个凸包,对多边形的所有边都做向着多边形的半平面交在判断一下是否构成凸包就可以了 一样的题目还有POJ3335 Video Surveillance Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3438   Accepted: 1523 Description A friend of y

LA 2218 (半平面交) Triathlon

题意: 有n个选手,铁人三项有连续的三段,对于每段场地选手i分别以vi, ui 和 wi匀速通过. 对于每个选手,问能否通过调整每种赛道的长度使得他成为冠军(不能并列). 分析: 粗一看,这不像一道计算几何的题目. 假设赛道总长度是1,第一段长x,第二段长y,第三段则是1-x-y 那么可以计算出每个选手完成比赛的时间Ti 对于选手i,若要成为冠军则有Ti < Tj (i ≠ j) 于是就有n-1个不等式,每个不等式都代表一个半平面. 在加上x>0, y>0, 1-x-y>0 这三个

POJ3525-Most Distant Point from the Sea(二分+半平面交)

Most Distant Point from the Sea Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3955   Accepted: 1847   Special Judge Description The main land of Japan called Honshu is an island surrounded by the sea. In such an island, it is natural t

bzoj 1007 水平可见直线 半平面交稀里糊涂的过了...

题意:按y=Ax+B的形式给出n(<=50000)条直线,求从y值为无穷大的地方向下看能看到的直线编号 一看到题目就想到半平面交,以每条直线的上方为一个半平面,求半平面的交,交集中存在的直线就是能看到的直线 但是写出来之后发现样例都过不了... 对于样例,如果允许半平面在边界处重叠那么答案是1,2,3,如果不允许只有1.. 然后抱着试一试的心理交上去了,结果竟然直接AC了.. 后来看题解只需要考虑交点x坐标.. bzoj 1007 水平可见直线 半平面交稀里糊涂的过了...,布布扣,bubuko

POJ 2540 半平面交求可行区域面积

Hotter Colder Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2343   Accepted: 981 Description The children's game Hotter Colder is played as follows. Player A leaves the room while player B hides an object somewhere in the room. Player

poj 3525 Most Distant Point from the Sea 半平面交 + 二分

题目来源: http://poj.org/problem?id=3525 分析: 题意:给定一个凸多边形,求多边形中距离边界最远的点到边界的距离. 思路 : 每次将凸多边形每条边往里平移d,判断是否存在核:二分d即可. 多边形边上的点(x , y)往里平移d 后的 坐标: s , e  为向量的 起点和终点, len 为起点和终点的距离, h 为平移的距离 x' = x + dx y' = y + dy dx = ( s.y - e.y ) / len * h ,( 原理 是 利用 三角形的相似

UVALive 4992 Jungle Outpost(半平面交)

题意:给你n个塔(点)形成一个顺时针的凸包,敌人可以摧毁任何塔,摧毁后剩下的塔再组成凸包 在开始的凸包内选一点为主塔,保证敌人摧毁尽量多塔时主塔都还在现在的凸包内,求出最多摧毁的塔 题解:这题关键就是选的主塔在不同的地方,敌人就会摧毁不同的塔来让你的主塔暴露 因此这样想,找出敌人摧毁不同的塔后形成的所有不同的凸包,再求出所有凸包的交就好 具体就是,首先枚举摧毁塔的个数k,再把摧毁任意k个塔所形成的所有不同的凸包求一个交,如果为空就代表了摧毁k个塔一定可以保证无论主塔在哪儿都可以暴露(关键) 而所