TOYS - POJ 2318(计算几何,叉积判断)
题目大意:给你一个矩形的左上角和右下角的坐标,然后这个矩形有 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(计算几何,叉积判断)的更多相关文章
- TOYS POJ 2318 计算几何 叉乘的应用
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 15060 Accepted: 7270 Description Calc ...
- POJ 2318/2398 叉积性质
2318 2398 题意:给出n条线将一块区域分成n+1块空间,再给出m个点,询问这些点在哪个空间里. 思路:由于只要求相对位置关系,而对具体位置不关心,那么易使用叉积性质得到相对位置关系(左侧/右侧 ...
- POJ 2398--Toy Storage(叉积判断,二分找点,点排序)
Toy Storage Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6534 Accepted: 3905 Descr ...
- POJ 2318 TOYS(叉积+二分)
题目传送门:POJ 2318 TOYS Description Calculate the number of toys that land in each bin of a partitioned ...
- 向量的叉积 POJ 2318 TOYS & POJ 2398 Toy Storage
POJ 2318: 题目大意:给定一个盒子的左上角和右下角坐标,然后给n条线,可以将盒子分成n+1个部分,再给m个点,问每个区域内有多少各点 这个题用到关键的一步就是向量的叉积,假设一个点m在 由ab ...
- POJ 2318 TOYS【叉积+二分】
今天开始学习计算几何,百度了两篇文章,与君共勉! 计算几何入门题推荐 计算几何基础知识 题意:有一个盒子,被n块木板分成n+1个区域,每个木板从左到右出现,并且不交叉. 有m个玩具(可以看成点)放在这 ...
- POJ 2398 Toy Storage(计算几何,叉积判断点和线段的关系)
Toy Storage Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3146 Accepted: 1798 Descr ...
- POJ 2318 TOYS (叉积+二分)
题目: Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and ...
- poj 2318(叉积判断点在线段的哪一侧)
TOYS Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13120 Accepted: 6334 Description ...
随机推荐
- 设置透明navigationBar
三行代码轻松实现透明navigationBar: [self.navigationController.navigationBar setBackgroundImage:[UIImage new] ...
- 网上流行的add(2)(3)(4)
网上有很多其他的各样的算法.其实这题就可以用javascript属性arguments.callee来实现,代码如下: function add(x){ var result=0; return fu ...
- Linux环境下添加ftp账号步骤
(1)远程登录Linux服务器所用的工具,免费开源,可以从网站上很容易就下载到. (2)打开putty,输入服务器IP,进入后按提示进入用户名和密码输入超级管理员 root,然后系统让输入密码,注意此 ...
- [转] 小tip: 使用CSS将图片转换成黑白(灰色、置灰) ---张鑫旭
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=2547 //zxx: ...
- Centos6.5最小化安装:配置网络和自启动服务
参考http://www.111cn.net/sys/CentOS/56456.htm 1.开启网络连接,禁止IPV6启用 1.开启网络连接 vi /etc/sysconfig/network-sc ...
- TCP/IP笔记 应用层(2)——FTP
1. FTP(File Transfer Protocol) 文件传送协议 FTP 只提供文件传送的一些基本的服务,它使用 TCP 可靠的运输服务.FTP 的主要功能是减少或消除在不同操作系统下处理文 ...
- MATLAB r2014a 下载+安装+激活
MATLAB r2014a,下载包就有7个多GB,装完占用9个多GB,慎装.界面还不错,稍有改良. 其实本文是下载+安装+破解啦.读书人的事,怎么能叫破解呢?所以我这里讲的是如何激活啦. MATLAB ...
- mysql update from 子查询
mssql 子查询更新 update log set uin= b.uinfrom log a,logs bwhere a.accountuin = b.accountuin mysql 不支持 up ...
- C#隐私信息(银行账户,身份证号码,名字)中间部分特殊字符替换(*)
最近做到一个关于银行的一个功能模块,需要将隐私信息银行账号中间部分用*代替,于是写下了,如下代码: /// <summary> /// 将传入的字符串中间部分字符替换成特殊字符 /// & ...
- jQuery中的data方法:
向元素附加数据,然后取回该数据: $("#btn1").click(function(){ $("div").data("greeting" ...