题目大意:给你一个矩形的左上角和右下角的坐标,然后这个矩形有 N 个隔板分割成 N+1 个区域,下面有 M 组坐标,求出来每个区域包含的坐标数。

 
分析:做的第一道计算几何题目....使用叉积判断方向,然后使用二分查询找到点所在的区域。
 
代码如下:
============================================================================================================================
#include<stdio.h>
#include<math.h>
using namespace std; const int MAXN = 5e3+;
const double PI = acos(-1.0); struct point
{
double x, y; point(int x=, int y=):x(x), y(y){}
};
struct Vector
{
point a, b; void InIt(point t1, point t2){a=t1, b=t2;}
double operator * (const point &p) const
{
return (p.x-b.x)*(a.y-b.y) - (p.y-b.y)*(a.x-b.x);
}
}; Vector line[MAXN]; int Find(int N, point a)
{
int L=, R=N; while(L <= R)
{
int Mid = (L+R) >> ; if(line[Mid] * a < )
R = Mid - ;
else
L = Mid + ;
} return R;
} int main()
{
int M, N;
double x1, x2, y1, y2, ui, li; while(scanf("%d", &N) != EOF && N)
{
scanf("%d%lf%lf%lf%lf", &M, &x1, &y1, &x2, &y2); int ans[MAXN]={}; line[].InIt(point(x1, y1), point(x1, y2));
for(int i=; i<=N; i++)
{
scanf("%lf%lf", &ui, &li);
line[i].InIt(point(ui, y1), point(li, y2));
}
while(M--)
{
scanf("%lf%lf", &ui, &li);
int i = Find(N, point(ui, li)); ans[i] += ;
} for(int i=; i<=N; i++)
printf("%d: %d\n", i, ans[i]);
printf("\n");
} return ;
}

重写...

#include<math.h>
#include<stdio.h>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std; const double EPS = 1e-;
const int maxn = ; int SIGN(const double &val)
{///整数返回1,负数返回-1, 0返回0
if(val > EPS)return ;
if(fabs(val) < EPS)return ;
return -;
} class Point
{
public:
Point(double x, double y): x(x), y(y){}
Point operator- (const Point& other)const
{///重载减号
return Point((x-other.x), (y - other.y));
}
double operator^(const Point& other)const
{///重载异或,定义叉积的运算
return (x*other.y) - (y*other.x);
}
public:
double x, y;
}; class Segment
{
public:
Segment(Point S, Point E) : S(S), E(E){}
int Mul(Point& other) const
{///用差乘判断点在线段的方向
return SIGN( (E-S)^(other-S) );
}
public:
Point S, E;
}; class SetSegment
{///定义一个线段的集合,有很多线段构成
public:
void Insert(const Segment& other)
{///插入一个线段
segs.push_back(other);
}
unsigned int Find(Point p)
{///查找点p靠近的最左边的线段的下标
unsigned int L=, R=segs.size()-, M; while(L <= R)
{
M = (L+R) / ;
Segment tmp = segs[M];
if(tmp.Mul(p) == -)
R = M-;
else
L = M+;
} return R;
}
public:
vector<Segment> segs;
};
int main()
{
int N, M;
double x1, x2, y1, y2, Ui, Li; while(scanf("%d", &N) != EOF && N)
{
scanf("%d%lf%lf%lf%lf", &M, &x1, &y1, &x2, &y2); SetSegment ss; ss.Insert(Segment(Point(x1, y1), Point(x1, y2)));
for(int i=; i<N; i++)
{
scanf("%lf%lf", &Ui, &Li);
ss.Insert(Segment(Point(Ui, y1), Point(Li, y2)));
} int ans[maxn] = {}; while(M--)
{
scanf("%lf%lf", &x1, &y1); int index = ss.Find(Point(x1, y1));
ans[index] += ;
} for(int i=; i<=N; i++)
printf("%d: %d\n", i, ans[i]);
printf("\n");
} return ;
}

TOYS - POJ 2318(计算几何,叉积判断)的更多相关文章

  1. TOYS POJ 2318 计算几何 叉乘的应用

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15060   Accepted: 7270 Description Calc ...

  2. POJ 2318/2398 叉积性质

    2318 2398 题意:给出n条线将一块区域分成n+1块空间,再给出m个点,询问这些点在哪个空间里. 思路:由于只要求相对位置关系,而对具体位置不关心,那么易使用叉积性质得到相对位置关系(左侧/右侧 ...

  3. POJ 2398--Toy Storage(叉积判断,二分找点,点排序)

    Toy Storage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6534   Accepted: 3905 Descr ...

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

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

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

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

  6. POJ 2318 TOYS【叉积+二分】

    今天开始学习计算几何,百度了两篇文章,与君共勉! 计算几何入门题推荐 计算几何基础知识 题意:有一个盒子,被n块木板分成n+1个区域,每个木板从左到右出现,并且不交叉. 有m个玩具(可以看成点)放在这 ...

  7. POJ 2398 Toy Storage(计算几何,叉积判断点和线段的关系)

    Toy Storage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3146   Accepted: 1798 Descr ...

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

    题目: Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and ...

  9. poj 2318(叉积判断点在线段的哪一侧)

    TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13120   Accepted: 6334 Description ...

随机推荐

  1. Windows服务安装方法

    操作系统:Win8.1 安装方法:在命令行窗口中输入:InstallUtil service.exe 出错原因:需要以管理员身份启动命令行.

  2. Quartz-2D绘图之路径(Paths)详解

    在上篇文章中,我们简单的理解了绘图上下文,今天我们来认识一下Quartz-2D中另一个重要的概念,路径(Paths). 一.理解路径 路径定义了一个或多个形状,或是子路径.一个子路径可由直线,曲线,或 ...

  3. 类库探源——System.Environment

    Environment 类: 提供有关当前环境和平台的信息以及操作它们的方法.此类不能被继承. 命名空间: System 程序集:   mscorlib.dll 继承关系: 常用属性(字段)和方法: ...

  4. C++专题 - 面向对象总结

    1.         什么是类?什么是对象?对象与类的关系是什么? 答:类就是相同的数据和相同的一组对象的集合,即类是对具有相同数据结构和相同操作的一类对象的描述: 对象是描述其属性的数据以及对这些数 ...

  5. ffmpeg与RTMP流媒体连接用法(翻译) http://www.chinavideo.org/forum.php?mod=viewthread&tid=15423

    最近浏览国外网站时候发现,翻译不准确的敬请谅解. 1.将文件当做直播送至liveffmpeg -re -i localFile.mp4 -c copy -f flv rtmp://server/liv ...

  6. jquery技巧(持续更新。。)

    (1)集合处理功能         //为索引为0,1,2的元素分别设置不同的字体颜色         $('p').each(function(i){               this.styl ...

  7. Python资源汇集

    Python资源汇集 一 实用教程 廖雪峰网站 第一,Python教程:提供了循序渐进,重点是可操作的实用教程. 第二,Web App 项目教程.给出一个用16天完成的Python Web APP项目 ...

  8. register 不允许 block 模式,而默认的是

    Exception in thread "main" java.nio.channels.IllegalBlockingModeException at java.nio.chan ...

  9. 关于如何设置reduce的个数

    在默认情况下,一个MapReduce Job如果不设置Reducer的个数,那么Reducer的个数为1.具体,可以通过JobConf.setNumReduceTasks(int numOfReduc ...

  10. 几个外国Delphi Blog网站

    http://blog.blong.com/search?updated-max=2012-09-19T03:21:00-07:00&max-results=7&start=42&am ...