Description

尼克发明了这样一个游戏:在一个坐标轴上,有一些圆,这些圆的圆心都在x轴上,现在给定一个x轴上的点,保证该点没有在这些圆内(以及圆上),尼克可以以这个点为圆心做任意大小的圆,他想知道自己做多可以与多少个给定的圆相交(相切也算,包含不算)。

Input

输入有多组数据 输入到文件尾

每一组数据有一个整数n(1<=n<=100000),表示总共有n个圆。

接下是n行,每行两个整数xi,ri表示该圆的圆心坐标和半径。

接下来一行为一个整数x,表示尼克选取点的位置。

x xi的范围[-10^9,10^9]  ri的范围[1,10^9]

总共有最多10组数据。

Output

每组数据输出一行,表示尼克最多可以覆盖多少个圆。

Sample Input

2
1 2
2 1
4

Sample Output

2

这个题目条件转换一下就是满足|r-d| <= R <= r+d的R就能与r半径的圆相交,其中d是两圆圆心的距离。

这样就变成了区间增值,然后查询区间中的最大值。

首先想到的是线段树,复杂度是O(2n*log(2n))。不过由于半径范围的值是离散的,所以采用map进行映射,使其连续。不过AC用时500ms左右。

然后发现其实直接处理后直接贪心就行。将所有区间的左右端点排序,排序时需要保存标记,用于记录这个端点是某个区间的左端点还是右端点。然后就是扫一遍,对于是左端点的自然值加一,对于右端点的自然值减一,然后贪心过程中的最大值。AC用时85ms左右。

贪心代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <algorithm>
#define LL long long using namespace std; struct node
{
LL index;
bool isleft;
}ind[]; int n, ans;
LL x[], r[], xx; bool cmp(node a, node b)
{
return a.index < b.index;
} LL Abs(LL aa)
{
if (aa < )
return -aa;
else
return aa;
} void Init()
{
LL d, Left, Right;
for (int i = ; i < n; ++i)
{
d = Abs(x[i]-xx);
Left = Abs(r[i]-d);
Right = r[i]+d;
ind[i<<].index = Left;
ind[i<<].isleft = true;
ind[i<<|].index = Right;
ind[i<<|].isleft = false;
}
sort(ind, ind+*n, cmp);
} int main()
{
//freopen("test.in", "r", stdin);
while (scanf("%d", &n) != EOF)
{
for (int i = ; i < n; ++i)
{
scanf("%lld%lld", &x[i], &r[i]);
}
scanf("%lld", &xx);
Init();
int len = *n;
int now = ;
ans = ;
for (int i = ; i < len; ++i)
{
if (ind[i].isleft)
now++;
else
now--;
ans = max(ans, now);
}
printf("%d\n", ans);
}
return ;
}

线段树代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <algorithm>
#define LL long long using namespace std; //线段树
//区间每点增值,求区间最值
const int maxn = ;
struct node
{
int lt, rt;
int val, add;
}tree[*maxn]; //向下更新
void PushDown(int id)
{
if (tree[id].add != )
{
tree[id<<].add += tree[id].add;
tree[id<<].val += tree[id].add;
tree[id<<|].add += tree[id].add;
tree[id<<|].val += tree[id].add;
tree[id].add = ;
}
} //向上更新
void PushUp(int id)
{
tree[id].val = max(tree[id<<].val, tree[id<<|].val);
} //建立线段树
void Build(int lt, int rt, int id)
{
tree[id].lt = lt;
tree[id].rt = rt;
tree[id].val = ;//每段的初值,根据题目要求
tree[id].add = ;
if (lt == rt)
{
//tree[id].add = ??;
return;
}
int mid = (lt + rt) >> ;
Build(lt, mid, id<<);
Build(mid+, rt, id<<|);
//PushUp(id);
} //增加区间内每个点固定的值
void Add(int lt, int rt, int id, int pls)
{
if (lt <= tree[id].lt && rt >= tree[id].rt)
{
tree[id].add += pls;
tree[id].val += pls;
return;
}
PushDown(id);
int mid = (tree[id].lt + tree[id].rt) >> ;
if (lt <= mid)
Add(lt, rt, id<<, pls);
if (rt > mid)
Add(lt, rt, id<<|, pls);
PushUp(id);
} //查询某段区间内的zuizhi
int Query(int lt, int rt, int id)
{
if (lt <= tree[id].lt && rt >= tree[id].rt)
return tree[id].val;
PushDown(id);
int mid = (tree[id].lt + tree[id].rt) >> ;
if (rt <= mid)
return Query(lt, rt, id<<);
if (lt > mid)
return Query(lt, rt, id<<|);
return max(Query(lt, rt, id<<), Query(lt, rt, id<<|));
} int n, cnt;
LL x[], r[], ind[], xx;
LL Left[], Right[];
map <LL, int> id; bool cmp(LL a, LL b)
{
return a < b;
} LL Abs(LL aa)
{
if (aa < )
return -aa;
else
return aa;
} void Init()
{
id.clear();
LL d;
for (int i = ; i < n; ++i)
{
d = Abs(x[i]-xx);
Left[i] = Abs(r[i]-d);
Right[i] = r[i]+d;
ind[i<<] = Left[i];
ind[i<<|] = Right[i];
}
sort(ind, ind+*n, cmp);
int len = *n;
cnt = ;
for (int i = ; i < len; ++i)
{
if (i == )
{
id[ind[]] = ;
continue;
}
if (ind[i] != ind[i-])
{
id[ind[i]] = ++cnt;
}
}
Build(, cnt, );
} int main()
{
//freopen("test.in", "r", stdin);
while (scanf("%d", &n) != EOF)
{
for (int i = ; i < n; ++i)
{
scanf("%lld%lld", &x[i], &r[i]);
}
scanf("%lld", &xx);
Init();
for (int i = ; i < n; ++i)
{
Add(id[Left[i]], id[Right[i]], , );
}
printf("%d\n", Query(, cnt, ));
}
return ;
}

ACM学习历程——NOJ1113 Game I(贪心 || 线段树)的更多相关文章

  1. ACM学习历程—POJ1151 Atlantis(扫描线 && 线段树)

    Description There are several ancient Greek texts that contain descriptions of the fabled island Atl ...

  2. ACM学习历程——HDU3333 Turing Tree(线段树 && 离线操作)

    Problem Description After inventing Turing Tree, 3xian always felt boring when solving problems abou ...

  3. ACM学习历程—HihoCoder1309任务分配(排序 && 贪心)

    http://hihocoder.com/problemset/problem/1309 题目大意是给定n个任务的起始时间,求问最少需要多少台机器. 有一个贪心的策略就是,如果说对于一个任务结束,必然 ...

  4. ACM学习历程—SNNUOJ 1239 Counting Star Time(树状数组 && 动态规划 && 数论)

    http://219.244.176.199/JudgeOnline/problem.php?id=1239 这是这次陕西省赛的G题,题目大意是一个n*n的点阵,点坐标从(1, 1)到(n, n),每 ...

  5. ACM学习历程—HDU 4287 Intelligent IME(字典树 || map)

    Description We all use cell phone today. And we must be familiar with the intelligent English input ...

  6. ACM学习历程—HDU2222 Keywords Search(字典树)

    Keywords Search Description In the modern time, Search engine came into the life of everybody like G ...

  7. BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库

    正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...

  8. 【题解】P1712 [NOI2016]区间(贪心+线段树)

    [题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...

  9. ACM学习历程—HDU5696 区间的价值(分治 && RMQ && 线段树 && 动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=5696 这是这次百度之星初赛2B的第一题,但是由于正好打省赛,于是便错过了.加上2A的时候差了一题,当时有思路,但 ...

随机推荐

  1. Android之Intent和Activity

    Intent能够说是Android的灵魂,程序跳转和传递数据的时候基本上就是靠Intent了.Intent在Android应用中是相当重要的,理解Intent相应用编程非常有帮助.在Android的官 ...

  2. 软件工程第2次作业——Visual Studio 2017下基于C/C++的VSTS单元测试实践

    Write one minute, test all day long. 环境确定 IDE:Microsoft Visual Studio 2017 Community 语言:C++ 单元测试工具:V ...

  3. oracle数据库表格操作

    create table dept--创建表格( deptno number(2) primary key, dname varchar2(9) check(dname=Upper(dname)), ...

  4. 用户对变量或寄存器进行位操作 、“|=”和“&=~”操作

    给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a的bit 3.在以上两个操作中,要保持其他位不变. 答案: ----------------------------------- ...

  5. 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树

    [BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...

  6. net上传文件的三种方法

    ASP.NET依托.net framework类库,封装了大量的功能,使得上传文件非常简单,主要有以下三种基本方法. 方法一:用Web控件FileUpload,上传到网站根目录. Test.aspx关 ...

  7. 2017-2018-1 20179209《Linux内核原理与分析》第四周作业

    本周学习内容为<跟踪分析MenuOS简单linux系统的启动过程>和教材中的进程调度及内核数据结构. 一.跟踪分析Linux内核的启动过程 这个实验我是在实验楼环境中完成的,最初想在自己的 ...

  8. sort()函数到底是怎样进行数字排序的

    很多人会用sort(),并不见得知道它具体是怎样给数字排序的.其实不知道也行,会用就可以,感兴趣的可以来看看. var numberArray = [2,4,1,3]; numberArray.sor ...

  9. 流畅python学习笔记第十八章:使用asyncio包处理并发(二)

    前面介绍了asyncio的用法.下面我们来看下如何用协程的方式来实现之前的旋转指针的方法 @asyncio.coroutine def spin(msg): write,flush=sys.stdou ...

  10. GDB打印内存命令

    用gdb查看内存 格式 x /nfu 参数说明 x是 examine 的缩写 n表示要显示的内存单元的个数 f表示显示方式, 可取如下值 x 按十六进制格式显示变量 d 按十进制格式显示变量 u 按十 ...