题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=5091

Problem Description
Recently, the γ galaxies broke out Star Wars. Each planet is warring for resources. In the Star Wars, Planet X is under attack by other planets. Now, a large wave of enemy spaceships is approaching. There is a very large Beam Cannon on the Planet X, and it is very powerful, which can destroy all the spaceships in its attack range in a second. However, it takes a long time to fill the energy of the Beam Cannon after each shot. So, you should make sure each shot can destroy the enemy spaceships as many as possible.

To simplify the problem, the Beam Cannon can shot at any area in the space, and the attack area is rectangular. The rectangle parallels to the coordinate axes and cannot rotate. It can only move horizontally or vertically. The enemy spaceship in the space can be considered as a point projected to the attack plane. If the point is in the rectangular attack area of the Beam Cannon(including border), the spaceship will be destroyed.

 
Input
Input contains multiple test cases. Each test case contains three integers N(1<=N<=10000, the number of enemy spaceships), W(1<=W<=40000, the width of the Beam Cannon’s attack area), H(1<=H<=40000, the height of the Beam Cannon’s attack area) in the first line, and then N lines follow. Each line contains two integers x,y (-20000<=x,y<=20000, the coordinates of an enemy spaceship).

A test case starting with a negative integer terminates the input and this test case should not to be processed.

 
Output
Output the maximum number of enemy spaceships the Beam Cannon can destroy in a single shot for each case.
 
Sample Input
2 3 4
0 1
1 0
3 1 1
-1 0
0 1
1 0
-1
 
Sample Output
2
2
 
Source
 
Recommend
hujie   |   We have carefully selected several similar problems for you:  5932 5931 5930 5929 5928 
 
题意:在平面上有n个点,现在有一个平行于坐标轴的矩形,宽为w 高为h,可以上下左右移动,但不能旋转,求这个矩形最多能够围住多少点?
 
思路:将输入的n个点按照横坐标从小到大排序,为了计算方便,在输入的时候可以对每个点记录一个标记点(打标记),如果输入的点是  node[i].x=x  node[i].y=y  node[i].v=1  那么 加一个标记点node[i+1].x=x+w  node[i+1].y=y  node[i+1].v= -1  这样对排序后的2*n个点进行计算时,只会有长为w范围的点会被计算,走出w长度范围的点会在计算node[i+1].v=-1 时清理掉。 那么现在考虑的点都在长为w的范围内,现在只需要考虑高了,可以用线段树计算对当前点node[i] 把node[i].y~node[i].y+h的区间长度都加上node[i].v  那么线段树求得的最大值就是当前区间点的值了, 为什么是这样呢? 因为考虑的点都在长为w范围里,所以只需要考虑y值,所以可以转换为这些点在一条直线上,求长为h的线段能覆盖最多的点数,考虑线段的上端点的位置,那么一个点对上端点的贡献为y~y+h 范围,端点的值就是这条线段的覆盖值;
 
代码如下:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=1e4+;
int n,w,h;
struct Node
{
int x,y,v;
}node[*N];
struct TNode
{
int f;
int m;
}tr[*N]; bool cmp(const Node s1,const Node s2)
{
if(s1.x==s2.x) return s1.v>s2.v;
return s1.x<s2.x;
}
void build(int l,int r,int i)
{
tr[i].f=; tr[i].m=;
if(l==r) return ;
int mid=(l+r)>>;
build(l,mid,i<<);
build(mid+,r,i<<|);
}
void pushdown(int i)
{
tr[i<<].f+=tr[i].f;
tr[i<<|].f+=tr[i].f;
tr[i<<].m+=tr[i].f;
tr[i<<|].m+=tr[i].f;
tr[i].f=;
}
void update(int l,int r,int i,int t)
{
if(l>=node[t].y&&r<=node[t].y+h)
{
tr[i].f+=node[t].v;
tr[i].m+=node[t].v;
return ;
}
if(tr[i].f!=) pushdown(i);
int mid=(l+r)>>;
if(node[t].y<=mid) update(l,mid,i<<,t);
if(node[t].y+h>mid) update(mid+,r,(i<<|),t);
tr[i].m=max(tr[i<<].m,tr[i<<|].m);
}
int main()
{
while(scanf("%d",&n)&&n>)
{
scanf("%d%d",&w,&h);
for(int i=;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
node[*i-].x=x;
node[*i-].y=y+*N;
node[*i-].v=;
node[*i].x=x+w;
node[*i].y=y+*N;
node[*i].v=-;
}
sort(node+,node+*n+,cmp);
build(,*N,);
int sum=;
for(int i=;i<=*n;i++)
{
update(,*N,,i);
sum=max(sum,tr[].m);
}
printf("%d\n",sum);
}
return ;
}

补充一下:HDU  4007  和这题相似(2016 ICPC大连站热身赛)

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=4007

题意:给了n个点,求一个正方形能围住的最大点数,同样正方形平行于坐标轴;

思路:与上面的题一样,但是这题数据范围很大,线段树的数组开不了这么大,那么必须要进行离散化;

代码如下:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
typedef long long LL;
LL L,R;
map<LL,LL>p;
struct Node
{
LL x,y;
LL v;
}node[];
struct TNode
{
LL m;
LL f;
}tr[];
bool cmp1(const Node s1,const Node s2)
{
if(s1.x==s2.x) return s1.v>s2.v;
return s1.x<s2.x;
}
bool cmp2(const Node s1,const Node s2)
{
return s1.y<s2.y;
}
void build(LL l,LL r,LL i)
{
tr[i].m=;
tr[i].f=;
if(l==r) return ;
LL mid=(l+r)>>;
build(l,mid,i<<);
build(mid+,r,i<<|);
}
void pushdown(LL i)
{
tr[i<<].f+=tr[i].f;
tr[i<<|].f+=tr[i].f;
tr[i<<].m+=tr[i].f;
tr[i<<|].m+=tr[i].f;
tr[i].f=;
}
void update(LL l,LL r,LL i,LL t)
{
if(l>=L&&r<=R){
tr[i].f+=t;
tr[i].m+=t;
return ;
}
pushdown(i);
LL mid=(l+r)>>;
if(L<=mid) update(l,mid,i<<,t);
if(R>mid) update(mid+,r,i<<|,t);
tr[i].m=max(tr[i<<].m,tr[i<<|].m);
}
int main()
{
LL n,r;
while(scanf("%lld%lld",&n,&r)!=EOF)
{
p.clear();
for(LL i=;i<=n;i++)
{
LL x,y;
scanf("%lld%lld",&x,&y);
node[*i-].x=x;
node[*i-].y=y;
node[*i-].v=;
node[*i-].x=x+r;
node[*i-].y=y;
node[*i-].v=-;
node[*i].x=x;
node[*i].y=y+r;
node[*i].v=;
}
sort(node+,node+*n+,cmp2);
///离散化
LL tot=,pre=-;
for(LL i=;i<=*n;i++)
{
if(node[i].y!=pre){
pre=node[i].y;
p[pre]=++tot;
}
}
sort(node+,node+*n+,cmp1);
build(,tot,);
LL sum=;
for(LL i=;i<=*n;i++)
{
if(node[i].v==) continue;
L=p[node[i].y];
R=p[node[i].y+r];
update(,tot,,node[i].v);
sum=max(sum,tr[].m);
}
printf("%lld\n",sum);
}
return ;
}

HDU 5091---Beam Cannon(线段树+扫描线)的更多相关文章

  1. [POI 2001+2014acm上海邀请赛]Gold Mine/Beam Cannon 线段树+扫描线

    Description  Byteman, one of the most deserving employee of The Goldmine of Byteland, is about to re ...

  2. hdu 5091 Beam Cannon(扫描线段树)

    题目链接:hdu 5091 Beam Cannon 题目大意:给定N个点,如今要有一个W∗H的矩形,问说最多能圈住多少个点. 解题思路:线段的扫描线,如果有点(x,y),那么(x,y)~(x+W,y+ ...

  3. HDU 1828“Picture”(线段树+扫描线求矩形周长并)

    传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...

  4. hdu 1828 Picture(线段树扫描线矩形周长并)

    线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...

  5. HDU 6096 String 排序 + 线段树 + 扫描线

    String Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Problem De ...

  6. HDU 5091 Beam Cannon (扫描线思想)

    题意:移动一个矩形,使矩形内包含的点尽量多. 思路:把一个点拆成两个事件,一个进(权值为1)一个出(权值为-1),将所有点按照x排序,然后扫描,对于每个x,用一个滑窗计算一下最大值,再移动扫描线.树状 ...

  7. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. hdu 5091 Beam Cannon

    题目大意: 有n个点(n<=10000),点的坐标绝对值不超过20000,然后问你用一个w*h(1<=w,h<=40000)的矩形,矩形的边平行于坐标轴,最多能盖住多少个点. 刘汝佳 ...

  9. HDU 3265 Posters ——(线段树+扫描线)

    第一次做扫描线,然后使我对线段树的理解发生了动摇= =..这个pushup写的有点神奇.代码如下: #include <stdio.h> #include <algorithm> ...

  10. 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...

随机推荐

  1. 爱上MVC~为CheckBoxFor和RadioButtonFor加个扩展方法吧(希望MVC5把这方法收纳——呵呵)

    回到目录 说在前 我都是喜欢把问题复杂化,还有总是喜欢把问题简单化,偷懒化,这也需就是一个程序员的追求吧,呵呵. 我不太喜欢重复的东西,当你看到页面上有一个以上相同的代码时,那可以说,你的代码有重构的 ...

  2. [数据库事务与锁]详解八:底理解数据库事务乐观锁的一种实现方式——CAS

    注明: 本文转载自http://www.hollischuang.com/archives/1537 在深入理解乐观锁与悲观锁一文中我们介绍过锁.本文在这篇文章的基础上,深入分析一下乐观锁的实现机制, ...

  3. Atitit RSA非对称加密原理与解决方案

    Atitit RSA非对称加密原理与解决方案 1.1. 一.一点历史 1 1.2. 八.加密和解密 2 1.3. 二.基于RSA的消息传递机制  3 1.4. 基于rsa的授权验证机器码 4 1.5. ...

  4. fir.im Weekly - iOS/Android 应用程序架构解析

    假如问你一个iOS or Android app的架构,你会从哪些方面来说呢? 本期 fir.im Weekly 收集了关于  iOS/Android 开发资源,也加入了一些关于 Web 前端方面的分 ...

  5. javascript实现汉诺塔动画效果

    javascript实现汉诺塔动画效果 当初以为不用html5也很简单,踩了javascript单线程的大坑后终于做出来了,没事可以研究下,对理解javascript的执行过程还是很有帮助的,代码很烂 ...

  6. 基于asp.net+MINIUI的项目----在线学习系统

    1 数据库列的自动计算: 描述:一张选课表,其中有学习的开始时间和结束时间,一个列用来计算学习的总时间(小时) 解决:选择该列 属性:计算列规范:公式:(datediff(hour,[StartTim ...

  7. HTML的音频和视频

    目录 [1]媒体格式 音频格式 视频格式 [2]元素 插件元素 HTML5元素 [3]HTML音频 [4]HTML视频 前面的话 多媒体元素(比如视频和音频)存储于媒体文件中,确定媒体类型的最常用的方 ...

  8. backbone库学习-Router

    backbone库的结构http://www.cnblogs.com/nuysoft/archive/2012/03/19/2404274.html 本文的例子来自http://blog.csdn.n ...

  9. Servlet的四种映射模式

    1. 路径匹配模式 <url-pattern>/test/*</url-pattern> 2. 扩展名匹配模式 <url-pattern>*.do</url- ...

  10. Javascript定时器(三)——setTimeout(func, 0)

    setTimeout(func, 0)可以使用在很多地方,拆分循环.模拟事件捕获.页面渲染等 一.setTimeout中的delay参数为0,并不是指马上执行 <script type=&quo ...