poj 2318 TOYS(计算几何:求叉积)

给出一个被n条线段分割的矩形

有m次询问,每次找到这个点所属的四边形

用二分的方法,找到对左侧线段叉积为正,右侧线段叉积为负的情况

直接套模板,代码如下:

/* ***********************************************
Author        :yinhua
Created Time  :2014年12月01日 星期一 19时19分20秒
File Name     :poj2318.cpp
************************************************ */

#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 5050
using namespace std;

struct Point {
    int x, y;
    Point() { }

    Point(int _x, int _y) {
        x = _x;y = _y;
    }

    Point operator -(const Point &b) const {
        return Point(x-b.x, y-b.y);
    }
    int operator *(const Point &b) const {
        return x*b.x+y*b.y;
    }
    int operator ^(const Point &b) const {
        return x*b.y-y*b.x;
    }
};

struct Line {
    Point s, e;
    Line() { }
    Line(Point _s, Point _e) {
        s = _s; e = _e;
    }
};

int xmult(Point p0, Point p1, Point p2) {//p0点与线段p1 p2的叉积
    return (p1-p0)^(p2-p0);
}

Line line[MAXN];
int ans[MAXN];

int main(void) {
    int m, n, x1, y1, x2, y2;
    bool first = true;
    while(~scanf("%d", &n) && n) {

        if(first) first = false;
        else puts("");

        scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);
        int ui, li;
        for(int i=0; i<n; ++i) {
            scanf("%d%d", &ui, &li);
            line[i] = Line(Point(ui, y1), Point(li, y2));
        }
        line[n] = Line(Point(x2, y1), Point(x2, y2));
        int x, y;
        Point p;
        memset(ans, 0, sizeof(ans));
        while(m--) {
            scanf("%d%d", &x, &y);
            p = Point(x, y);
            int l = 0, r = n;
            int tmp;
            while(l <= r) {
                int mid = (l+r)>>1;
                if(xmult(p, line[mid].s, line[mid].e) < 0) {//点在当前线的左侧
                    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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值