题目大意:有一个矩形盒子,盒子里会有一些木块线段,并且这些线段是按照顺序给出的,有n条线段,把盒子分层了n+1个区域,然后有m个玩具,这m个玩具的坐标是已知的,问最后每个区域有多少个玩具

解题思路:因为线段是有序给出,所以不用排序,判断某个点在哪个区域,采用二分法,将某个点和线段的叉积来判断这个点是在线的左边或者右边,根据这个来二分找出区域

代码和思路参考与此链接:http://blog.csdn.net/wangjian8006

这也算我入门计算几何的第一道题了,首先看了一些有关资料,了解到叉积的重要性!!有2点,p1,p2构成一条线段L,L左边有一点p3,右边有一点p4,则(p1-p2)x(p3-p1)>0,(p1-p2)x(p4-p1)<0。

也就是说在L左边的点叉积>0,右边的<0。

剩下的就是二分找答案了,在记录到数组中,最后输出。

#include <iostream>
using namespace std;
#define _MAXL_ 5010 typedef struct{
int x, y;
}POINT; typedef struct{
POINT first,second;
}LINE; class CBox{
private:
int nTop,nLeft,nRight,nButtom;
int nCountLine; //记录盒子里有多少条线
LINE *pLine; //记录线的信息
int *pRange; //记录区间中的玩具有多少个
int Multi(POINT p1,POINT p2,POINT p0); //叉积计算
public:
CBox();
virtual ~CBox();
void SetBorder(int top,int left,int right,int buttom); //设置盒子矩形坐标
void AddLine(int first,int second); //在盒子中增加一条线
int GetRange(int val); //得到某个区间中的玩具个数
void SetToy(POINT toy); //在盒子里放一个玩具
}; CBox::CBox(){
nCountLine = 0;
pLine = new LINE[_MAXL_];
pRange = new int[_MAXL_];
memset(pRange,0,sizeof(pRange)*_MAXL_);
} CBox::~CBox(){
delete []pLine;
delete []pRange;
} void CBox::SetBorder(int top,int left,int right,int buttom){
nTop = top;
nLeft = left;
nRight = right;
nButtom = buttom;
} void CBox::AddLine(int topx,int buttomx){
pLine[nCountLine].first.x = topx;
pLine[nCountLine].first.y = nTop;
pLine[nCountLine].second.x = buttomx;
pLine[nCountLine].second.y = nButtom;
nCountLine++;
} int CBox::GetRange(int val){
return pRange[val];
} int CBox::Multi(POINT p1,POINT p2,POINT p0){
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
} void CBox::SetToy(POINT toy){ //利用二分查找,查找出该点在哪个区间
int l, r, mid;
l=0,r=nCountLine-1;
while (l < r){
mid = (l+r)>>1;
if (Multi(toy, pLine[mid].first, pLine[mid].second) > 0) l = mid + 1;
else r = mid;
}
if (Multi(toy, pLine[l].first, pLine[l].second) < 0) pRange[l]++;
else pRange[l+1]++;
} int main(){
int i,fx,lx;
POINT a,b;
int n,m;
while(cin>>n && n){
cin>>m>>a.x>>a.y>>b.x>>b.y;
CBox box;
box.SetBorder(a.y,a.x,b.x,b.y);
for(i = 0;i < n;i++){
cin>>fx>>lx;
box.AddLine(fx,lx);
} for(i = 0;i < m;i++){
cin>>a.x>>a.y;
box.SetToy(a);
} for(i = 0;i <= n;i++){
cout<<i<<": "<<box.GetRange(i)<<endl;
}
cout<<endl;
}
return 0;
}

  

POJ 2318 TOYS(计算几何)的更多相关文章

  1. poj 2318 TOYS(计算几何 点与线段的关系)

    TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12015   Accepted: 5792 Description ...

  2. POJ 2318 TOYS(计算几何)

    跨产品的利用率推断点线段向左或向右,然后你可以2分钟 代码: #include <cstdio> #include <cstring> #include <algorit ...

  3. POJ 2318 TOYS(叉积+二分)

    题目传送门:POJ 2318 TOYS Description Calculate the number of toys that land in each bin of a partitioned ...

  4. poj 2318 TOYS (二分+叉积)

    http://poj.org/problem?id=2318 TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 101 ...

  5. 简单几何(点与线段的位置) POJ 2318 TOYS && POJ 2398 Toy Storage

    题目传送门 题意:POJ 2318 有一个长方形,用线段划分若干区域,给若干个点,问每个区域点的分布情况 分析:点和线段的位置判断可以用叉积判断.给的线段是排好序的,但是点是无序的,所以可以用二分优化 ...

  6. POJ 2318 TOYS && POJ 2398 Toy Storage(几何)

    2318 TOYS 2398 Toy Storage 题意 : 给你n块板的坐标,m个玩具的具体坐标,2318中板是有序的,而2398无序需要自己排序,2318要求输出的是每个区间内的玩具数,而231 ...

  7. 向量的叉积 POJ 2318 TOYS & POJ 2398 Toy Storage

    POJ 2318: 题目大意:给定一个盒子的左上角和右下角坐标,然后给n条线,可以将盒子分成n+1个部分,再给m个点,问每个区域内有多少各点 这个题用到关键的一步就是向量的叉积,假设一个点m在 由ab ...

  8. poj 2318 TOYS &amp; poj 2398 Toy Storage (叉积)

    链接:poj 2318 题意:有一个矩形盒子,盒子里有一些木块线段.而且这些线段坐标是依照顺序给出的. 有n条线段,把盒子分层了n+1个区域,然后有m个玩具.这m个玩具的坐标是已知的,问最后每一个区域 ...

  9. 【POJ】2318 TOYS ——计算几何+二分

    TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10281   Accepted: 4924 Description ...

  10. 2018.07.03 POJ 2318 TOYS(二分+简单计算几何)

    TOYS Time Limit: 2000MS Memory Limit: 65536K Description Calculate the number of toys that land in e ...

随机推荐

  1. C++@冒号(:)和双冒号(::)的用法

    转自:http://blog.csdn.net/zimingjushi/article/details/6549390 1.冒号(:)用法 (1)表示机构内位域的定义(即该变量占几个bit空间) ty ...

  2. C++@语句块

    #include <iostream> using namespace std; int main() { { int x=1; cout << x << endl ...

  3. Java——设计模式(单例模式)

     /* * 设计模式: 对问题行之有效的解决方式,其实他是一种思想. * 1.单例设计模式. *  解决问题:  就是可以保证一个列在内存中的对象唯一性. * *如何保证对象的唯一性: *1. 不 ...

  4. Scrum 项目2.0

    阅读教材第8章,8.1~8.3节 P157~168,了解获取用户需求的办法,每个组可以选择一二加以应用. 8.4节P168-171 查阅NABCDA模型的具体说明. 2.SCRUM 流程的步骤 1 完 ...

  5. phpstorm用正则删除PHP代码空行小技巧

    有很多小伙伴会遇到代码空行特别多,但是一行一行删除肯定很烦躁,这时候就需要用到批量删除空行. 怎么批量删除空行呢? 我的办法是用正则把所有空行找到,然后一键全部替换. 首先把Match Case和Re ...

  6. MiniCRT 64位 linux 系统移植记录:64位gcc的几点注意

    32位未修改源码与修改版的代码下载: git clone git@github.com:youzhonghui/MiniCRT.git MiniCRT 64位 linux 系统移植记录 MiniCRT ...

  7. HTTP缓存ETAG和Last-Modified

    1) 什么是"Last-Modified"? 在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文 ...

  8. linux库

     将库函数打包成一个单元使之能够在运行时被多个进程共享的技术,这种技术能够节省磁盘空间和RAM. 一. 静态库:1.概念:    静态库就是一些目标文件的集合,以.a结尾.静态库在程序链接的时候使用, ...

  9. 【转】Asp.net中时间格式化的6种方法详细总结

    1. 数据控件绑定时格式化日期方法: 代码如下: <asp:BoundColumn DataField="AddTime" HeaderText="添加时间&quo ...

  10. IE和FireFox中JS兼容之event .

    event对象 IE 中可以直接使用 event 对象,而 FF 中则不可以,解决方法之一如下:var theEvent = window.event || arguments.callee.call ...