计算几何——点线关系(叉积)poj2318

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

const double esp = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;

int sgn(double x){
    if(fabs(x) < esp)return 0;
    if(x < 0)return -1;
    else return 1;
}
inline double sqr(double x){return x*x;}

struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y):x(_x),y(_y){}
    void input(){scanf("%lf%lf",&x,&y);}
    void output(){printf("%.2lf %.2lf\n",x,y);}
    bool operator==(Point b)const {
        return sgn(x-b.x)==0 && sgn(y-b.y)==0;
    }
    bool operator < (Point b)const {//判左下
        if( sgn(x-b.x)==0 )  //横坐标相等
            return sgn(y-b.y)<0;
        return x<b.x;
    }
    Point operator - (const Point &b)const {
        return Point(x-b.x,y-b.y);
    }
    double operator ^(const Point &b)const {
        return x*b.y-y*b.x;
    }
    double operator *(const Point &b)const {
        return x*b.x+y*b.y;
    }
    double len(){
        return hypot(x,y);
    }
    double len2(){
        return x*x+y*y;
    }
    double distance(Point p){
        return hypot(x-p.x,y-p.y);
    }
    Point operator +(const Point &b)const {
        return Point(x+b.x,y+b.y);
    }
    Point operator *(const double &k)const {
        return Point(x*k,y*k);
    }
    Point operator /(const double &k)const {
        return Point(x/k,y/k);
    }
    double rad(Point a,Point b){
        Point p=*this;
        return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
    }
    Point trunc(double r){
        double l=len();
        if(!sgn(l))return *this;
        r/=l;
        return Point(x*r,y*r);
    }
    Point rotleft(){
        return Point(-y,x);
    }
    Point rotright(){
        return Point(y,-x);
    }
    Point rotate(Point p,double angle){
        Point v=(*this)-p;
        double c=cos(angle),s=sin(angle);
        return Point(p.x+v.x*c-v.y*s, p.y+v.x*s+v.y*c);
    }
};
struct Line{
    Point s,e;
    Line(){}
    Line(Point s,Point e):s(s),e(e){}
    bool operator ==(Line v){
        return (s==v.s) && (e==v.e);
    }
    Line(Point p,double angle){
        s=p;
        if(sgn(angle-pi/2)==0)
            e=s+Point(0,1);
        else e=s+Point(1,tan(angle));
    }
    Line(double a,double b,double c){
        if(sgn(a)==0){
            s=Point(0,-c/b);
            e=Point(1,-c/b);
        }
        else if(sgn(b)==0){
            s=Point(-c/a,0);
            e=Point(-c/a,1);
        }
        else {
            s=Point(0,-c/b);
            e=Point(1,(-c-a)/b);
        }
    }
    void input(){
        s.input();
        e.input();
    }
    void adjust(){
        if(e<s)swap(e,s);
    }
    double length(){
        return s.distance(e);
    }
    double angle(){
        double k=atan2(e.y-s.y,e.x-s.x);
        if(sgn(k)<0)k+=pi;
        if(sgn(k-pi)==0) k-=pi;
        return k;
    }
    int relation(Point p){
        int c=sgn((p-s)^(e-s));
        if(c<0)return 1;
        else if(c>0)return 2;
        else return 3;
    }
    bool pointonseg(Point p){
        return sgn((p-s)^(e-s))==0 && sgn((p-s)*(p-e))<=0;
    }
    bool parallel(Line v){
        return sgn((e-s)^(v.e-v.s))==0;
    }
    int segcrossseg(Line v){
        int d1=sgn((e-s)^(v.s-s));
        int d2=sgn((e-s)^(v.e-s));
        int d3=sgn((v.e-v.s)^(s-v.s));
        int d4=sgn((v.e-v.s)^(e-v.s));
        if( (d1^d2)==-2 && (d3^d4)==-2) return 2;
        return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) ||
            (d2==0 && sgn((v.e-s)*(v.e-e))<=0) ||
            (d3==0 && sgn((s-v.s)^(s-v.e))<=0) ||
            (d4==0 && sgn((e-v.s)^(e-v.e))<=0);
    }
    int linecrossseg(Line v){
        int d1=sgn((e-s)^(v.s-s));
        int d2=sgn((e-s)^(v.e-s));
        if(d1^d2==-2)return 2;
        return d1==0 || d2==0;
    }
    int linecrossline(Line v){
        if((*this).parallel(v))
            return v.relation(s)==3;
        return 2;
    }
    Point crosspoint(Line v){
        double a1=(v.e-v.s)^(s-v.s);//面积
        double a2=(v.e-v.s)^(e-v.s);
        return Point((s.x*a2-e.x*a1)/(a2-a1),
                        (s.y*a2-e.y*a1)/(a2-a1));
    }
    double dispointtoline(Point p){
        return fabs((p-s)^(e-s))/length();
    }
    double dispointtoseg(Point p){
        if(sgn((p-s)*(e-s))<0 || sgn((p-e)*(s-e))<0)
            return min(p.distance(s),p.distance(e));
        return dispointtoline(p);
    }
    double dissegtoseg(Line v){
        return min(min(dispointtoseg(v.s),dispointtoseg(v.e)),
                    min(v.dispointtoline(s),v.dispointtoline(e)));
    }
    Point lineprog(Point p){//s+vt
        return s+( ((e-s)*((e-s)*(p-s)))/(e-s).len2() );
    }
    Point symmetrypoint(Point p){
        Point q=lineprog(p);
        return Point(2*q.x-p.x,2*q.y-p.y);
    }
};

const int maxn = 5050;
Line line[maxn];
int ans[maxn];

int main(){
    int n,m;
    double x1,y1,x2,y2;
    bool first=1;
    while(scanf("%d",&n)==1 && n){
        if(first)first=0;
        else puts("");
        scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);
        double Ui,Li;
        for(int i=0;i<n;i++){
            scanf("%lf%lf",&Ui,&Li);
            line[i]=Line(Point(Li,y2),Point(Ui,y1));
        }
        line[n]=Line(Point(x2,y2),Point(x2,y1));
        /*for(int i=0;i<=n;i++)
            line[i].adjust();*/

        double x,y;
        Point p;
        memset(ans,0,sizeof ans);

        while(m--){
            scanf("%lf%lf",&x,&y);
            p=Point(x,y);
            int l=0,r=n,tmp=0,mid;
            while(l<=r){
                mid=l+r>>1;
                if(line[mid].relation(p)==1){//p在直线的左边
                    tmp=mid;r=mid-1;
                }
                else l=mid+1;
            }
            ans[tmp]++;
        }
        for(int i=0;i<=n;i++)
            printf("%d: %d\n",i,ans[i]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/zsben991126/p/10920441.html

时间: 2024-11-05 21:57:28

计算几何——点线关系(叉积)poj2318的相关文章

poj 2398 Toy Storage(计算几何 点线关系)

Toy Storage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4588   Accepted: 2718 Description Mom and dad have a problem: their child, Reza, never puts his toys away when he is finished playing with them. They gave Reza a rectangular box

POJ 2318 TOYS(点与直线的关系 叉积&amp;&amp;二分)

题目链接 题意: 给定一个矩形,n个线段将矩形分成n+1个区间,m个点,问这些点的分布. 题解: 思路就是叉积加二分,利用叉积判断点与直线的距离,二分搜索区间. 代码: 最近整理了STL的一些模板,发现真是好用啊orz,为啥以前没发现呢,可能是比较懒吧-.- #include <stdio.h> #include <string.h> #include <cmath> #include <iostream> #include <queue> #i

湖南程序设计竞赛赛题总结 XTU 1237 Magic Triangle(计算几何)

这个月月初我们一行三人去湖南参加了ccpc湖南程序设计比赛,虽然路途遥远,六月的湘潭天气燥热,不过在一起的努力之下,拿到了一块铜牌,也算没空手而归啦.不过通过比赛,还是发现我们的差距,希望这几个月自己努力思考,积极刷题,为九月份acm网络赛做准备! 言归正传说说这道题目,这也是这次比赛想到AC比较高的题目,不过我们还是没能完成,下面我就来总结一下此题的一些思路和方法. Magic Triangle Problem Description: Huangriq is a respectful acm

poj 2780 Linearity 最多共线点经典问题

题意: 给n个点,其中最多有多少点共线(n<1000). 分析: 这是一个经典问题,朴素n^3解法:枚举n^2条直线,判断每条直线与多少点相交,复杂度n^3.明显会超时.这是n^2logn的解法:枚举每个点,对某个点与其他点连的n条直线按斜率排序,设这些直线中斜率相同的直线有k条,则k更新答案.这里想着重说一下斜率的问题,网上很多代码都是直接算斜率的,但计算几何的题目不推荐用斜率,最好用叉积代替有关斜率的一切计算,因为1)斜率的取值范围非常大,如果有中间计算有乘法很容易爆数据表示范围,对于要求精

牛人的ACM经验 (转)

一:知识点 数据结构: 1,单,双链表及循环链表 2,树的表示与存储,二叉树(概念,遍历)二叉树的 应用(二叉排序树,判定树,博弈树,解答树等) 3,文件操作(从文本文件中读入数据并输出到文本文 件中) 4,图(基本概念,存储结构,图的运算) 数学知识 1,离散数学知识的应用(如排列组合.简单的图论,数 理逻辑) 2,数论知识 3,线性代数 4,组合代数 5,计算几何 二 算法 1,排序算法(冒抛法,插入排序,合并排序,快速排 序,堆排序) 2,查找(顺序查找,二分发) 3,回溯算法 4,递归算

要开始算法了 什么顺序呢?

ACM 中常用的算法有哪些? 在网上看到别人ACM学习的心得,转载过来,源地址不记得了,当时是百度的.内容如下: 网络上流传的答案有很多,估计提问者也曾经去网上搜过.所以根据自己微薄的经验提点看法. 我ACM初期是训练编码能力,以水题为主(就是没有任何算法,自己靠动脑筋能够实现的),这种题目特点是麻烦,但是不难,30-50道题目就可以了. 然后可以接触一下基础的算法,我感觉搜索方向的比较不错,可以解决很多问题,深搜,广搜,然后各种剪枝能力的锻炼. 搜索感觉不错了就可以去看看贪心,图论,和动态规划

转:转一个搞ACM需要的掌握的算法. .

要注意,ACM的竞赛性强,因此自己应该和自己的实际应用联系起来.  适合自己的才是好的,有的人不适合搞算法,喜欢系统架构,因此不要看到别人什么就眼红,  发挥自己的长处,这才是重要的. 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,  因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打  出来.  1.最短路(Floyd.Dijstra,BellmanFord)  2.最小生成树(先写个prim,kruscal要用并查集,不好写)

算法初学者指南

摘自网络,对于这个训练计划,我只能膜拜,~ 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码, 因为太常用,所以要练到写时不用想,10-15 分钟内打完,甚至关掉显示器都可以把程序打 出来. 1.最短路(Floyd.Dijstra,BellmanFord) 2. 最小生成树(先写个prim,kruscal要用并查集,不好写) 3.大数(高精度)加减乘除 4.二分查找. (代码可在五行以内) 5.叉乘.判线段相交.然后写个凸包. 6.BFS.DFS,同时熟练hash表(

BZOJ1822 Frozen Nova 冷冻波

1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec  Memory Limit: 64 MB Description WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵.我们认为,巫妖和小精灵都可以看成是平面上的点. 当巫妖和小精灵之间的直线距离不超过R,且巫妖看到小精灵的视线没有被树木阻挡(也就是说,巫妖和小精灵的连线与任何树木都没有公共点)的话,巫妖就可以瞬间杀灭一个小精灵.