向量的叉积 POJ 2318 TOYS & POJ 2398 Toy Storage
2015-04-01 11:27
477 查看
POJ 2318:
题目大意:给定一个盒子的左上角和右下角坐标,然后给n条线,可以将盒子分成n+1个部分,再给m个点,问每个区域内有多少各点
这个题用到关键的一步就是向量的叉积,假设一个点m在 由abcd围成的四边形区域内,那么向量ab, bc, cd, da和点的关系就是,点都在他们的同一侧,我是按照逆时针来算的,所以只需要判断叉积是否小于0就行了。还有一个问题就是这个题要求时间是2s,所以直接找,不用二分也能过,不过超过1s了,最好还是二分来做,二分时间170ms,二分的时候要把最左边的一条边和最右边的一条边都要加到数组中去
代码一(直接找区域)
View Code
题目大意:给定一个盒子的左上角和右下角坐标,然后给n条线,可以将盒子分成n+1个部分,再给m个点,问每个区域内有多少各点
这个题用到关键的一步就是向量的叉积,假设一个点m在 由abcd围成的四边形区域内,那么向量ab, bc, cd, da和点的关系就是,点都在他们的同一侧,我是按照逆时针来算的,所以只需要判断叉积是否小于0就行了。还有一个问题就是这个题要求时间是2s,所以直接找,不用二分也能过,不过超过1s了,最好还是二分来做,二分时间170ms,二分的时候要把最左边的一条边和最右边的一条边都要加到数组中去
代码一(直接找区域)
#include<iostream> #include <cstdio> #include <string.h> #include <algorithm> using namespace std; const int N = 5500; struct point{ int x, y; }; struct Edge{ point Start, End; }; Edge edge ; int n, m, ans , res ; point upper_left, lower_left, upper_right, lower_right, p ;//各个角 bool cmp(Edge e1, Edge e2) { if (e1.Start.x != e2.Start.x) return e1.Start.x < e2.Start.x; return e1.End.x < e2.End.x; } double direction(point a, point b, point c)//判断方向,判断点c在向量ab的哪一侧,如果返回是负值则在逆时针那侧 { point t1, t2; t1.x = c.x - a.x; t1.y = c.y - a.y; t2.x = b.x - a.x; t2.y = b.y - a.y; return (t1.x * t2.y * 1.0 - t1.y * t2.x * 1.0); } void dichotomization_edge(point tmp) { int left, right, mid; left = 0; right = n + 1; mid = (left + right) >> 1; while (left < right) { if (left + 1 == right) { ans[left]++; break; } double d = direction(edge[mid].Start, edge[mid].End, tmp); if (d < 0) left = mid; else right = mid; mid = (left + right) >> 1; } } int main() { while (~scanf("%d", &n) && n) { memset(ans, 0, sizeof(ans)); point t1, t2; scanf("%d %d %d %d %d", &m, &upper_left.x, &upper_left.y, &lower_right.x, &lower_right.y); lower_left.x = upper_left.x; lower_left.y = lower_right.y; upper_right.x = lower_right.x; upper_right.y = upper_left.y; edge[0].Start = upper_left; edge[0].End = lower_left; for (int i = 1; i <= n; i++) { scanf("%d %d", &t1.x, &t2.x); t1.y = upper_left.y; t2.y = lower_right.y; edge[i].Start = t1; edge[i].End = t2; } edge[n + 1].Start = upper_right; edge[n + 1].End = lower_right; point tmp; sort(edge, edge + n + 1, cmp); for (int i = 0; i < m; i++) { scanf("%d %d", &tmp.x, &tmp.y); dichotomization_edge(tmp); } memset(res, 0, sizeof(res)); for (int i = 0; i <= n; i++) if (ans[i] != 0) res[ans[i]]++; printf("Box\n"); for (int i = 0; i < 5000; i++) if (res[i] != 0) printf("%d: %d\n", i, res[i]); } return 0; }
View Code
相关文章推荐
- poj 2318 TOYS & poj 2398 Toy Storage (叉积)
- 【叉积性质】POJ 2318 TOYS && POJ 2398 Toy Storage
- poj 2318 TOYS & poj 2398 Toy Storage (叉积)
- POJ 2318 TOYS && POJ 2398 Toy Storage(几何)
- POJ_2318_TOYS&&POJ_2398_Toy Storage_二分+判断直线和点的位置关系
- 简单几何(点与线段的位置) POJ 2318 TOYS && POJ 2398 Toy Storage
- POJ 2318:TOYS & POJ 2398:Toy Storage 计算几何
- POJ 2318 TOYS + 2398 Toy Storage(计算几何叉积)
- [POJ 2318] Toys (向量叉积的基本运用)
- POJ 2398 Toy Storage 叉积 和2318基本一样
- POJ 2318 TOYS (向量叉积的右手法则)
- POJ 2318 TOYS || POJ 2398 Toy Storage
- POJ 2318 TOYS/POJ 2398 Toy Storage
- poj 2318 TOYS(叉积+二分)
- poj 2318 TOYS(叉积+二分)
- POJ 2398 Toy Storage(计算几何,叉积判断点和线段的关系)
- POJ 2398:Toy Storage _叉积性质
- TOYS - POJ 2318 叉积
- Poj 2318 TOYS (叉积+二分)
- POJ 2318 TOYS 二分+叉积