POJ 2318:

题目大意:给定一个盒子的左上角和右下角坐标,然后给n条线,可以将盒子分成n+1个部分,再给m个点,问每个区域内有多少各点

这个题用到关键的一步就是向量的叉积,假设一个点m在 由abcd围成的四边形区域内,那么向量ab, bc, cd, da和点的关系就是,点都在他们的同一侧,我是按照逆时针来算的,所以只需要判断叉积是否小于0就行了。还有一个问题就是这个题要求时间是2s,所以直接找,不用二分也能过,不过超过1s了,最好还是二分来做,二分时间170ms,二分的时候要把最左边的一条边和最右边的一条边都要加到数组中去

代码一(直接找区域)

#include<iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int N = ;
struct point{
int x, y;
};
int n, m, ans[];
point upper_left, lower_left, upper_right, lower_right, p[N];
double direction(point a, point b, point c)//判断方向
{
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);
}
int main()
{
while (~scanf("%d", &n) && n)
{
memset(ans, , sizeof(ans));
int a, b;
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;
for (int i = ; i < * n; i++)
{
scanf("%d %d", &a, &b);
p[i].x = a; p[i].y = upper_left.y;
p[++i].x = b; p[i].y = lower_right.y; }
point tmp;
double d1, d2, d3, d4;
for (int i = ; i < m; i++)
{
scanf("%d %d", &tmp.x, &tmp.y);
//判断是否在第一个区域内
d1 = direction(upper_left, lower_left, tmp);
d2 = direction(lower_left, p[], tmp);
d3 = direction(p[], p[], tmp);
d4 = direction(p[], upper_left, tmp);
if (d1 <= && d2 <= && d3 <= && d4 <= )
{
ans[]++;
continue;
}
bool flag = false;
for (int j = ; j < * n - ; j += )
{
d1 = direction(p[j], p[j + ], tmp);
d2 = direction(p[j + ], p[j + ], tmp);
d3 = direction(p[j + ], p[j + ], tmp);
d4 = direction(p[j + ], p[j], tmp);
if (d1 <= && d2 <= && d3 <= && d4 <= )
{
ans[j / + ]++;
flag = true;
break;
}
}
if (flag)
continue;
//d1 = direction(p[2 * n - 2], p[2 * n - 1], tmp);
//d2 = direction(p[2 * n - 1], lower_right, tmp);
//d3 = direction(lower_right, upper_right, tmp);
//d4 = direction(upper_right, p[n * 2 - 2], tmp);
//if (d1 <= 0 && d2 <= 0 && d3 <= 0 && d4 <= 0)
ans[n]++;
}
for (int i = ; i <= n; i++)
printf("%d: %d\n", i, ans[i]);
puts("");
} return ;
}

代码二(二分法)

#include<iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int N = ;
struct point{
int x, y;
};
int n, m, ans[];
point upper_left, lower_left, upper_right, lower_right, p[N];//各个角
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(point tmp)//二分法判断在那块区间内
{
int left, right, mid;
left = ; right = n + ; mid = (left + right) >> ;
while (left < right)
{
if (left + == right)
{
ans[left]++;
break;
}
double d = direction(p[mid * ], p[mid * + ], tmp);
if (d < )
left = mid;
else
right = mid;
mid = (left + right) >> ;
}
}
int main()
{
while (~scanf("%d", &n) && n)
{
memset(ans, , sizeof(ans));
int a, b;
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;
p[] = upper_left;//将边角点加入p数组,为了二分 好计算
p[] = lower_left;
for (int i = ; i < * n + ; i++)
{
scanf("%d %d", &a, &b);
p[i].x = a; p[i].y = upper_left.y;
p[++i].x = b; p[i].y = lower_right.y; }
p[ * n + ] = upper_right;
p[ * n + ] = lower_right;
point tmp;
for (int i = ; i < m; i++)
{
scanf("%d %d", &tmp.x, &tmp.y);
dichotomization(tmp); }
for (int i = ; i <= n; i++)
printf("%d: %d\n", i, ans[i]);
puts("");
} return ;
}

POJ 2398:

这道题和上一题类似,包括主要过程也一样,但是有个条件不一样,上一个题它给的n条线时有序的,就是从左往右的,但是这个没有顺序,是随便给的,所以要把它排一下序,最后让求的,假设是一个区域内有t个点,的这样的区域有多少个,按照升序打印出来:

代码如下:

#include<iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = ;
struct point{
int x, y;
};
struct Edge{
point Start, End;
};
Edge edge[N];
int n, m, ans[N], res[N];
point upper_left, lower_left, upper_right, lower_right, p[N];//各个角
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 = ; right = n + ; mid = (left + right) >> ;
while (left < right)
{
if (left + == right)
{
ans[left]++;
break;
}
double d = direction(edge[mid].Start, edge[mid].End, tmp);
if (d < )
left = mid;
else
right = mid;
mid = (left + right) >> ;
}
}
int main()
{
while (~scanf("%d", &n) && n)
{
memset(ans, , 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[].Start = upper_left;
edge[].End = lower_left;
for (int i = ; 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 + ].Start = upper_right;
edge[n + ].End = lower_right;
point tmp;
sort(edge, edge + n + , cmp);
for (int i = ; i < m; i++)
{
scanf("%d %d", &tmp.x, &tmp.y);
dichotomization_edge(tmp); }
memset(res, , sizeof(res));
for (int i = ; i <= n; i++)
if (ans[i] != )
res[ans[i]]++;
printf("Box\n");
for (int i = ; i < ; i++)
if (res[i] != )
printf("%d: %d\n", i, res[i]);
} return ;
}

向量的叉积 POJ 2318 TOYS & POJ 2398 Toy Storage的更多相关文章

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

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

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

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

  3. POJ 2318 TOYS/POJ 2398 Toy Storage

    计算几何终于开坑了... 叉积+二分. #include<iostream> #include<cstdio> #include<cstring> #include ...

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

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

  5. poj 2398 Toy Storage(计算几何)

    题目传送门:poj 2398 Toy Storage 题目大意:一个长方形的箱子,里面有一些隔板,每一个隔板都可以纵切这个箱子.隔板将这个箱子分成了一些隔间.向其中扔一些玩具,每个玩具有一个坐标,求有 ...

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

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

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

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

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

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

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

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

随机推荐

  1. 【USACO 1.2.1】挤牛奶

    [问题描述] 三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶.第一个农民在300时刻(从5点开始计时,秒为单位)给他的牛挤奶,一直到1000时刻.第二个农民在700时刻开始,在 1200时刻结束.第 ...

  2. cocos2d-x 读取 json 文件并用 jsoncpp 做解析

    一码胜万言(请看注释) CclUtil.h // // CclUtil.h // PracticeDemo // // Created by kodeyang on 8/1/13. // // #if ...

  3. 深入Java虚拟机读书笔记第一章Java体系结构介绍

    第1章 Java体系结构介绍 Java技术核心:Java虚拟机 Java:安全(先天防bug的设计.内存).健壮.平台无关.网络无关(底层结构上,对象序列化和RMI为分布式系统中各个部分共享对象提供了 ...

  4. Websocket 与代理服务器如何交互? How HTML5 Web Sockets Interact With Proxy Servers

    How HTML5 Web Sockets Interact With Proxy Servers Posted by Peter Lubberson Mar 16, 2010 With the re ...

  5. phpstorm 配置

    JetBrains PhpStorm 8注册码一枚 username :cf96PiPYt271u1TC License Key : 97807-12042010 00001GctOKh8f206hl ...

  6. phonegap学习入门

    phonegap 开发入门 PhoneGap官方网站上有详细的入门示例教程,这里,我针对使用PhoneGap进行Android移动应用的开发对其官网的Get Started进行一些介绍.补充. Ste ...

  7. C题

    C - C Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu   Description   Ass ...

  8. 『Python』 爬取 WooYun 论坛所有漏洞条目的相关信息

    每个漏洞条目包含: 乌云ID,漏洞标题,漏洞所属厂商,白帽子,漏洞类型,厂商或平台给的Rank值 主要是做数据分析使用:可以分析某厂商的各类型漏洞的统计:或者对白帽子的能力进行分析..... 数据更新 ...

  9. 初识Java反射机制

    1.ClassLoader的类加载机制:并非一次性加载,而是需要的时候加载(运行期间动态加载)(Class文件加载到内存的代码段),static语句块在加载后执行一次.dynamic语句块(就是一个语 ...

  10. Regularized Linear Regression with scikit-learn

    Regularized Linear Regression with scikit-learn Earlier we covered Ordinary Least Squares regression ...