POJ 2318 TOYS | 二分+判断点在多边形内
题意:
给一个矩形的区域(左上角为(x1,y1) 右下角为(x2,y2)),给出n对(u,v)表示(u,y1) 和 (v,y2)构成线段将矩形切割
这样构成了n+1个多边形,再给出m个点,问每个多边形内有多少个点.
读入为n,m,x1,y1,x2,y2
n个数对(u,v),m个数对(x,y) (n,m<=5000)
题解:
很暴力的想法是对于每个点,枚举每个多边形进行检查.
但是多组数据就很江
考虑一下判断点在多边形内的射线法可知
枚举一个多边形的时候就可以知道点在多边形的左边还是右边
这样我们对每个点二分一下他属于那个多边形,依靠上述性质就可以在nlogn时间内做完
#include<cstdio>
#include<algorithm>
#include<cstring>
typedef long long ll;
#define N 5010
using namespace std;
int n,m,x1,x2,y1,y2,up[N],down[N],cnt[N],t;
struct point
{
int x,y;
point (){} ;
point (int _x,int _y) :
x(_x),y(_y) {};
bool operator < (const point &rhs) const
{
if (x==rhs.x) return y<rhs.y;
return x<rhs.x;
}
inline int operator * (const point &rhs) const
{
return x*rhs.y-y*rhs.x;
}
inline point operator - (const point &rhs) const
{
return point(x-rhs.x,y-rhs.y);
}
friend inline int dot (const point &lhs,const point &rhs)
{
return lhs.x*rhs.x+lhs.y*rhs.y;
}
}toy[N];
bool isinline (const point &p1,const point &p2,const point &p3)
{
int det=(p1-p3)*(p2-p3);
if (det!=0) return 0;
int Dot=dot(p1-p3,p2-p3);
return Dot<=0;
}
struct polygon
{
point p[10];
int inner (const point &pp)
{
int cnt=0;
for (int i=1;i<=4;i++)
{
if (isinline(p[i],p[i+1],pp)) return 1;
int d1=p[i].y-pp.y,d2=p[i+1].y-pp.y;
int del=(p[i]-pp)*(p[i+1]-pp);
if ( (del>=0 && d1>=0 && d2<0) ||
(del<=0 && d1<0 && d2>=0) ) cnt++;
}
return cnt;
}
}pol[N];
void solve()
{
sort(toy+1,toy+1+m);
memset(cnt,0,sizeof(cnt));
for (int i=0;i<=n;i++)
{
pol[i].p[1]=pol[i].p[5]=point(up[i],y1);
pol[i].p[4]=point(down[i],y2);
pol[i].p[3]=point(down[i+1],y2);
pol[i].p[2]=point(up[i+1],y1);
}
for (int i=1;i<=m;i++)
{
int l=0,r=n,mid;
while (l<=r)
{
mid=l+r>>1;
int res=pol[mid].inner(toy[i]);
if (res&1)
{
cnt[mid]++;
break;
}
if (res>0) l=mid+1;
else r=mid;
}
}
}
int main()
{
while (scanf("%d",&n),n)
{
if (++t!=1) puts("");
scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
for (int i=1;i<=n;i++)
scanf("%d%d",&up[i],&down[i]);
for (int i=1,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
toy[i]=point(x,y);
}
up[0]=down[0]=x1,up[n+1]=down[n+1]=x2;
solve();
for (int i=0;i<=n;i++)
printf("%d: %d\n",i,cnt[i]);
}
return 0;
}
POJ 2318 TOYS | 二分+判断点在多边形内的更多相关文章
- poj 2318 TOYS (二分+叉积)
http://poj.org/problem?id=2318 TOYS Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 101 ...
- POJ 2318 TOYS(叉积+二分)
题目传送门:POJ 2318 TOYS Description Calculate the number of toys that land in each bin of a partitioned ...
- poj 2318 叉积+二分
TOYS Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13262 Accepted: 6412 Description ...
- zoj 1081 判断点在多边形内
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=81Points Within Time Limit: 2 Second ...
- 判断点在多边形内算法的C++实现
目录 1. 算法思路 2. 具体实现 3. 改进空间 1. 算法思路 判断平面内点是否在多边形内有多种算法,其中射线法是其中比较好理解的一种,而且能够支持凹多边形的情况.该算法的思路很简单,就是从目标 ...
- hdu 1756:Cupid's Arrow(计算几何,判断点在多边形内)
Cupid's Arrow Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- php之判断点在多边形内的api
1.判断点在多边形内的数学思想:以那个点为顶点,作任意单向射线,如果它与多边形交点个数为奇数个,那么那个点在多边形内,相关公式: <?php class AreaApi{ //$area是一个多 ...
- ZOJ 1081 Points Within | 判断点在多边形内
题目: 给个n个点的多边形,n个点按顺序给出,给个点m,判断m在不在多边形内部 题解: 网上有两种方法,这里写一种:射线法 大体的思想是:以这个点为端点,做一条平行与x轴的射线(代码中射线指向x轴正方 ...
- R树判断点在多边形内-Java版本
1.什么是RTree 待补充 2.RTree java依赖 rtree的java开源版本在GitHub上:https://github.com/davidmoten/rtree 上面有详细的使用说明 ...
随机推荐
- hdu_4944_FSF’s game
FSF has programmed a game. In this game, players need to divide a rectangle into several same square ...
- xml的应用与dtd约束
1.xml的应用 *不同的系统之间的传输数据(qq消息传输) *用来表示生活中有关系的数据(省市区的包含关系) *经常用在文件配置 **比如现在连接数据库,肯定知道数据库的名称和密码及用户名. ...
- 使用union all 命令之后如何对hive表格进行去重
业务场景大概是这样的,这里由两个hive表格,tableA 和 tableB, 格式内容都是这样的: uid cate1 cate2 在hive QL中,我们知道union有着自动去重的功能,但是那是 ...
- 006---Django静态文件配置
静态文件:Js.Css.Fonts.Image等 这个不难.在setting.py文件加一行 # 别名 用户在url地址栏输入127.0.0.1:8000/static/文件 可以直接访问static ...
- GCJ:2008 Round1AA-Minimum Scalar Product(有序数组倒序乘积和最小)
题目链接:https://code.google.com/codejam/contest/32016/dashboard#s=p0 Minimum Scalar Product This contes ...
- PHP.30-TP框架商城应用实例-后台6-商品会员价格删除-外键,级联操作
商品会员价格删除 需求:当删除一件商品时,这件商品对应的会员价格也应该从会员价格表{price,level_id,goods_id}中删除掉. 有两种删除方法 1.在钩子函数_before_delet ...
- zedboard烧写SD卡启动linux镜像
1. 先把SD卡格式化,然后把镜像文件拷贝到SD卡,下面应该是没有文件系统的 2. 插上SD卡,Zedboard设置启动模式,有5个跳线帽,配置如下,上电启动 3. 看下串口的输出
- TerminateProcess
Remarks The TerminateProcess function is used to unconditionally cause a process to exit. The state ...
- laravel5.5授权系统
目录 1. Gates 1.1 一个简单的使用Gates的例子 1.2 编写Gates 1.3 授权动作 2. policy策略 2.1 还是先看个例子 2.2 编写策略 2.3 授权策略 2.3.1 ...
- 剑指Offer - 九度1521 - 二叉树的镜像
剑指Offer - 九度1521 - 二叉树的镜像2013-11-30 23:32 题目描述: 输入一个二叉树,输出其镜像. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入 ...