POJ2318:TOYS(叉积判断点和线段的关系+二分)&&POJ2398Toy Storage
题目:http://poj.org/problem?id=2318
题意:
给定一个如上的长方形箱子,中间有n条线段,将其分为n+1个区域,给定m个玩具的坐标,统计每个区域中的玩具个数。(其中这些线段有序且不相交)
解答:
因为线段是有序给出,所以不用排序,判断某个点在哪个区域,采用二分法,将某个点和线段的叉积来判断这个点是在线的左边或者右边,根据这个来二分找出区域。
这是第一道计算几何的题目,怎么说呢,对于二分的边界问题还有点搞不清楚,这次是对线段二分,感觉二分真的很有用处。
开阔思维!!!具体请看代码。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <queue>
#define inf 0x3f3f3f3f
#define eps 1e-9
typedef long long ll;
using namespace std;
int n,m,x,y,x2,y2,temp;
int a[][],point[][],sum[]; void er(int l,int r,int keyx,int keyy)
{
ll X1,Y1,X2,Y2;
int mid;
while(l<r)
{
mid=l+(r-l)/;
X1=a[mid][]-keyx;
Y1=y-keyy;
X2=a[mid][]-keyx;
Y2=y2-keyy;
if(X1*Y2-X2*Y1<=)
r=mid;
else l=mid+;
}
sum[l]++;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n!=)
{
scanf("%d%d%d%d%d",&m,&x,&y,&x2,&y2);
for(int i=; i<n; i++)
scanf("%d%d",&a[i][],&a[i][]);
a[n][]=a[n][]=x2;//保证所有点都能找到叉积<=0的线段
for(int i=; i<m; i++)
{
scanf("%d%d",&point[i][],&point[i][]);
}
memset(sum,,sizeof(sum));
for(int i=; i<m; i++)
{
er(,n,point[i][],point[i][]);
}
for(int i=; i<=n; i++)
{
printf("%d: %d\n",i,sum[i]);
}
cout<<endl;
}
return ;
}
大神写的规范代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; struct Point {
int x, y;
}; struct Line {
Point a, b;
} line[]; int cnt[]; int 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 BSearch(Point a, int n) {
int l, r, mid; l = ; r = n-;
while (l < r) {
mid = (l + r) >> ;
if (Multi(a, line[mid].a, line[mid].b) > ) l = mid + ;
else r = mid;
}
if (Multi(a, line[l].a, line[l].b) < ) cnt[l]++;
else cnt[l+]++;
} int main()
{
int n, m, x1, y1, x2, y2;
int i, t1, t2;
Point a; while (scanf ("%d", &n) && n) {
scanf ("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);
for (i = ; i < n; i++) {
scanf ("%d%d", &t1, &t2);
line[i].a.x = t1;
line[i].a.y = y1;
line[i].b.x = t2;
line[i].b.y = y2;
}
memset(cnt, , sizeof (cnt));
for (i = ; i < m; i++) {
scanf ("%d%d", &a.x, &a.y);
BSearch(a, n);
}
for (i = ; i <= n; i++)
printf ("%d: %d\n", i, cnt[i]);
printf("\n");
}
return ;
}
POJ2398:
本题和poj2318 TOYS大致一样,但有一些不同。
1:输入是无序的,需要自己排序。
2:输出是输出拥有相同玩具数的区块有几个。 (区块里的玩具数:相同玩具数的区块个数)
知道题意就很好做了。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <queue>
#define inf 0x3f3f3f3f
#define eps 1e-9
typedef long long ll;
using namespace std;
int n,m,x,y,x2,y2,temp;
int point[][],sum[];
struct node
{
int a1,a2;
} a[];
int cmp(const void *a,const void *b)
{
struct node *aa=(struct node *)a;
struct node *bb=(struct node *)b;
return aa->a1-bb->a1;
}
void er(int l,int r,int keyx,int keyy)
{
ll X1,Y1,X2,Y2;
int mid;
while(l<r)
{
mid=l+(r-l)/;
X1=a[mid].a1-keyx;
Y1=y-keyy;
X2=a[mid].a2-keyx;
Y2=y2-keyy;
if(X1*Y2-X2*Y1<=)
r=mid;
else l=mid+;
}
sum[l]++;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n!=)
{
scanf("%d%d%d%d%d",&m,&x,&y,&x2,&y2);
for(int i=; i<n; i++)
scanf("%d%d",&a[i].a1,&a[i].a2);
a[n].a1=a[n].a2=x2;
qsort(a,n+,sizeof(a[]),cmp);
for(int i=; i<m; i++)
{
scanf("%d%d",&point[i][],&point[i][]);
}
memset(sum,,sizeof(sum));
for(int i=; i<m; i++)
{
er(,n,point[i][],point[i][]);
}
printf("Box\n");
int ha[];
memset(ha,,sizeof(ha));
for(int i=; i<=m; i++)
{
if(sum[i])
ha[sum[i]]++;
}
for(int i=; i<=; i++)
{
if(ha[i]) printf("%d: %d\n",i,ha[i]);
}
}
return ;
}
POJ2318:TOYS(叉积判断点和线段的关系+二分)&&POJ2398Toy Storage的更多相关文章
- POJ 2398 Toy Storage (叉积判断点和线段的关系)
题目链接 Toy Storage Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4104 Accepted: 2433 ...
- POJ 2398 Toy Storage(计算几何,叉积判断点和线段的关系)
Toy Storage Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3146 Accepted: 1798 Descr ...
- POJ2318 TOYS(叉积判断点与直线的关系+二分)
Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a prob ...
- poj2318(叉积判断点在直线左右+二分)
题目链接:https://vjudge.net/problem/POJ-2318 题意:有n条线将矩形分成n+1块,m个点落在矩形内,求每一块点的个数. 思路: 最近开始肝计算几何,之前的几何题基本处 ...
- POJ2318 TOYS[叉积 二分]
TOYS Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14433 Accepted: 6998 Description ...
- [poj2318]TOYS(直线与点的位置关系)
解题关键:计算几何入门题,通过叉积判断. 两个向量的关系: P*Q>0,Q在P的逆时针方向: P*Q<0,Q在P的顺时针方向: P*Q==0,Q与P共线. 实际就是用右手定则判断的. #i ...
- POJ-2318 TOYS 计算几何 判断点在线段的位置
题目链接:https://cn.vjudge.net/problem/POJ-2318 题意 在一个矩形内,给出n-1条线段,把矩形分成n快四边形 问某些点在那个四边形内 思路 二分+判断点与位置关系 ...
- TOYS - POJ 2318(计算几何,叉积判断)
题目大意:给你一个矩形的左上角和右下角的坐标,然后这个矩形有 N 个隔板分割成 N+1 个区域,下面有 M 组坐标,求出来每个区域包含的坐标数. 分析:做的第一道计算几何题目....使用叉积判断方 ...
- poj 2318(叉积判断点在线段的哪一侧)
TOYS Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13120 Accepted: 6334 Description ...
随机推荐
- JQuery Show()的几种效果 总有一种是你需要的
1 show()方法和hide()方法 $("selector").show() 从display:none还原元素默认或已设置的display属性$("selecto ...
- jquery库实现iframe自适应内容高度和宽度
javascript原生和jquery库实现iframe自适应内容高度和宽度---推荐使用jQuery的代码! <iframe src="index.php" id=&qu ...
- Android Studio 工具栏添加图标
本文中 Android Studio 的版本为 Android Studio 2.2 ,操作系统为 Windows,如有操作不同,可能是版本差异.在工具栏中添加一些常用的图标有利于我们开发,举例说明: ...
- 一个区域只能放置一个组件,如果想在一个区域放置多个组件就需要使用Panel来装载
五种布局管理器: Flow Layout(流式布局):按照组件添加到容器中的顺序,顺序排放组件位置.默认为水平排列,如果越界那么会向下排列.排列的位置随着容器大小的改变而改变. Panel默认的布局管 ...
- 【BZOJ】1633: [Usaco2007 Feb]The Cow Lexicon 牛的词典(dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1633 一开始也想到了状态f[i]表示i以后的字符串最少删的数 然后想到的转移是 f[i]=min{f ...
- ERROR getting 'android:label' attribute: attribute is not a string value
这个的原因很多地方都有描述,原因多半是多国语言string.xml 有的有这个值, 有的没有. 关键是怎么定位? 实际上他报错的是当前处理的xml element有问题, 而出错的时候盖住了要处理的. ...
- Spring RestTemplate post
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); map.add("auditPara ...
- 编程之美 set 15 高效率地安排见面会
题目 有 n 个学生分别对 m 个见面会感兴趣, 为了满足所有学生的要求, HR 希望每个学生都能参加自己感兴趣的所有见面会 思路 1. 假设某一个同学同时对k个小组感兴趣, 那么这k个小组两两之间都 ...
- 第三篇:CUDA 标准编程模式
前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式编写,即使是调用库,库的底层也是这个模式实现的. 模式描述 1. 定义需要在 device 端执行的核函数.( 函数声明前加 ...
- Android 获取当前应用的版本号和当前系统的版本号
1.获取当前程序版本名 我们可以在AndroidManifest.xml中设置程序的版本号等,如android:versionName="1.0",那如果想在代码中获取这个版本号呢 ...