>传送门<

前言


跟学知识一样,做题目的确是也是常做常新。这道题当时的确已经解决了,国庆前工作室学长还有其他人又提起这道题,我说不就暴力枚举贪心么,后来学长说那你不好证明贪心的正确性!我一想的确是这样的,基本上没有人讲这怎么三次贪心选取就可以了,有点像瞎搞的样子。于是就又去看了$multiset$的做法,其实用线段树也可以,作用都是较快的维护最大值,只要思维到位了,选择恰当的数据结构就能做出来。

题意


现在给你n个点 ,让你横着划三条线间距为r 然后竖着划三条线间距同样为r ,求经过最多的点数

思路


比赛看到这题的时候觉得能做,但是一看时间限制是5s,搞得我有不敢去碰了,就没有写,但是赛后再看其实并没有那么复杂。有的人是用线段树去写的,感觉线段树简直万能~其实直接求也是可以的,感觉有点暴力(就算是暴力我也想不到QAQ)

下面介绍两者做法,一种是贪心枚举瞎搞,一种是用$multiset+$思维。

贪心枚举(为什么说他瞎搞,这么做感觉是对的,也的确能做,但是你很难证明贪心的正确性,不过在比赛的时候也不失为一种好方法)

正常思路肯定时枚举横的三线和竖的三线,找到最大,这样时O(n2)的复杂度。

一般二维的题目我们枚举一维,比如枚举横三线,

预处理竖三线,以每个x为三线的左线,求出三线包含的气球个数(cntX[i] + cntX[i + r] + cntX[i + r * 2],对竖三线包含的气球数进行从大到小排序,贪心进行选取

然后枚举纵坐标,算出以当前纵坐标为底线的三横线包含的气球个数,由于这样会重复,所以对于横三线已经选取的点竖三线就不再进行选取,之后取最大值和竖三线的值相加就行。

最后,按照这种贪心的取法就能得到最大值(对竖三线的值贪心三次就能得到,这是我没想到的,100会更保险一点)

Code

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + ;
int n, r, cntX[maxn*], cntY[maxn*], res;
struct Point {
int x, y;
bool operator<(const Point &rhs)const {
return x > rhs.x;
}
} a[maxn], sum[maxn]; int main()
{
scanf("%d%d", &n, &r);
for (int i = ; i < n; i++) {
scanf("%d%d", &a[i].x, &a[i].y);
cntX[a[i].x]++;
}
for (int i = ; i < maxn; i++) {
sum[i].x = cntX[i] + cntX[i + r] + cntX[i + r * ];
sum[i].y = i;
}
sort(sum, sum + maxn);
for (int i = ; i < ; i++) {
memset(cntY, , sizeof(cntY));
for (int j = ; j < n; j++)
if (a[j].x != sum[i].y && a[j].x != sum[i].y + r && a[j].x != sum[i].y + r * )
cntY[a[j].y]++;
int my = ;
for (int j = ; j < maxn; j++)
my = max(my, cntY[j] + cntY[j + r] + cntY[j + r * ]);
res = max(res, my + sum[i].x);
}
printf("%d\n", res);
return ;
}
/*
总体的思路就是分别对横纵坐标暴力枚举三条线经过的点数(去重),然后通过贪心的思想选取,最后出来的就是最大值
首先直接用sum[i].x枚举三条竖线(i, i+r, i+2*r)能够经过的点数,sum[i].y记录当前枚举是从横坐标为i这条竖线开始的
然后对sum[i]按x从大到小排序,贪心的选取sum[i]后,肯定不能直接枚举三条横线能够经过的点数,因为这样会有重复。
那怎么办呢?我们就先对cntY[a[j].y]进行处理,假如我选取的sum[i]中已经包含a[j]这个点了,那么我的cntY[[a[j].y]就不能加1,因为这个点已经被计算过
现在当然就可以枚举三条横线能够经过的点数,取最大值和sum[i].x相加就是当前总共能经过的最多点数
*/

 

$multiset+$思维

官方题解说的已经很详细了,这种题其实很考验思维。

我们用$f(i)$表示中间一枪打第$i$行,能够射中的气球个数,用$g(i)$表示中间一枪打第$i$列,能射中的气球个数。

用$multiset$存所有$f(i)$的值,枚举中间一枪打第$x$列,将对每一个位于第$x-r,x+r$列的气球,将它们影响到的行(共三行)的$f(j)$的值更新,然后更新$multiset$内的元素。

中间一枪打第$x$列的最大收益即$g(x)$+(当前$multiset$内最大元素)。

Code

#include<cstring>
#include<string>
#include<set>
#include<vector>
using namespace std;
const int maxn = 1e5 + ;
const int M = 1e5; int cnt[maxn];
vector <int> h[maxn];
multiset<int> s;
void add(int x) {
auto p = s.find(cnt[x]);
s.erase(p);
cnt[x]++;
s.insert(cnt[x]);
}
void del(int x) {
auto p = s.find(cnt[x]);
s.erase(p);
cnt[x]--;
s.insert(cnt[x]);
}
//multiset + 思维
int main()
{
int n, r, x, y, ans = ;
scanf("%d%d", &n, &r);
for (int i = ; i < n; i++) {
scanf("%d%d", &x, &y);
h[x].push_back(y);
if (x - r >= ) h[x - r].push_back(y);
if (x + r <= M) h[x + r].push_back(y);
cnt[y]++;
if (y - r >= ) cnt[y - r]++;
if (y + r <= M) cnt[y + r]++;
}
for (int i = ; i <= M; i++) s.insert(cnt[i]);//往multiset里添加行的气球数
for (int i = ; i <= M; i++) {
int res = (int)h[i].size();//三列的气球总数
for (int j = ; j < res ; j++) {//如果影响了三行,就更新
del(h[i][j]);
if (h[i][j] - r >= ) del(h[i][j] - r);
if (h[i][j] + r <= M) del(h[i][j] + r);
}
ans = max(ans, res + (int)(*s.rbegin()));//取最大值
for (int j = ; j < res ; j++) {//再更新回去
add(h[i][j]);
if (h[i][j] - r >= ) add(h[i][j] - r);
if (h[i][j] + r <= M) add(h[i][j] + r);
}
}
printf("%d\n", ans);
return ;
}

2019牛客暑期多校训练营(第十场)F-Popping Balloons的更多相关文章

  1. 2019牛客暑期多校训练营(第三场)- F Planting Trees

    题目链接:https://ac.nowcoder.com/acm/contest/883/F 题意:给定n×n的矩阵,求最大子矩阵使得子矩阵中最大值和最小值的差值<=M. 思路:先看数据大小,注 ...

  2. 2019牛客暑期多校训练营(第三场) F.Planting Trees(单调队列)

    题意:给你一个n*n的高度矩阵 要你找到里面最大的矩阵且最大的高度差不能超过m 思路:我们首先枚举上下右边界,然后我们可以用单调队列维护一个最左的边界 然后计算最大值 时间复杂度为O(n*n*n) # ...

  3. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  4. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  5. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  6. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  7. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  8. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

  9. [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem

    链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

  10. 2019牛客暑期多校训练营(第二场)J-Subarray(思维)

    >传送门< 前言 这题我前前后后看了三遍,每次都是把网上相关的博客和通过代码认真看了再思考,然并卵,最后终于第三遍也就是现在终于看懂了,其实懂了之后发现其实没有那么难,但是的的确确需要思维 ...

随机推荐

  1. STM32F0_HAL库驱动描述——基于F1的USART串口IT中断实现解析

    从原子F103 HAL库基础串口例程来看HAL程序结构: 从main函数开始,首先是HAL库两个函数的初始化: HAL_Init(): Stm32_Clock_Init(RCC_PLL_MUL9); ...

  2. 【NOIP2015】扫雷游戏-C++

    描述 扫雷游戏是一款十分经典的单机小游戏.在 n 行 m 列的雷区中有一些格子含有地雷 (称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开一个非地雷格时, 该格将会出现一个数字--提示周围 ...

  3. <float.h>中DBL_TRUE_MIN的定义和作用

    搬运自己2016年11月22日于SegmentFault发表的文章.链接:https://segmentfault.com/a/1190000007565915 在学习C Prime Plus的过程中 ...

  4. Learning the Depths of Moving People by Watching Frozen

    基于双目的传统算法 对静止的物体, 在不同的 viewpoints 同一时刻进行拍摄, 根据拍摄到的结果, 使用三角测量算法计算出平面 2D 图像在 3D 图像中的坐标 单目 Ground Truth ...

  5. 洛谷P1396 营救 题解

    题目:https://www.luogu.org/problemnew/show/P1396 分析: 这其实一看就是一个最短路的近似模板的题目,但我们要注意到两个区之间可能会有多条道路,所以说我们只需 ...

  6. 跟着大彬读源码 - Redis 5 - 对象和数据类型(上)

    相信很多人应该都知道 Redis 有五种数据类型:字符串.列表.哈希.集合和有序集合.但这五种数据类型是什么含义?Redis 的数据又是怎样存储的?今天我们一起来认识下 Redis 这五种数据结构的含 ...

  7. Git介绍以及安装

    Git的作者是大名鼎鼎的Linux之父Linus Torvalds. Git是一个分布式的版本控制系统,Git三个字母的含义可以理解为"Global Information Tracker& ...

  8. C语言入门6-选择结构--f语句-switch

    一.     什么是选择结构? 选择结构,也称为分支结构!! 选择结构就是根据    给定的判定条件,判断结果, 并根据  判断的结果   来控制程序的流程 (流程图中,   菱形框 是有来判断的 , ...

  9. webpack基础知识

    一.基础 1 安装 npm i -g webpack webpack-cli // 推荐安装至本地 npm i -D webpack webpack-cli 2 webpck基础使用 2.1 webp ...

  10. php框架内的数据库操作(微擎,tp,yii2)

    微擎数据库操作 关键字 查询 pdo_get pdo_getcolumn pdo_getall pdo_getslice pdo_fetchcolumn pdo_fetchall 示例: array ...