热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ACDream(18)DisappearingBlocks:离散化与二分查找

题目链接:请点击这里。本题将图形视为波动,其中波峰被淹没时部分数减少,而波谷被淹没时部分数增加。因此,需要预先处理所有波峰和波谷的位置。特别地,图形的两端点需要特殊处理,可以通过设置边界条件来简化问题。
### 题目链接
- [点击访问](#)

### 背景描述
在解决ACDream (18) Disappearing Blocks的问题时,我们将给定的图形视作一系列波动。具体来说,当波峰被水淹没时,图形的部分数量会减少;相反,当波谷被水淹没时,部分数量会增加。基于这一特性,解题的关键在于准确识别并处理所有的波峰和波谷。

### 解题思路
为了有效地处理波峰和波谷,我们首先对图形的两端点进行特殊处理,通常通过将`h[0]`和`h[n+1]`设定为-1来实现。接下来,提取所有波峰和波谷的高度,并按高度降序排列这些点。在遍历这些点时,需要注意的是,对于具有相同高度但非连续的点,应将它们作为一个整体进行处理,确保每次高度变化时的计算结果是正确的。

### 实现细节
1. **数据预处理**:初始化边界条件,并读取输入数据。
2. **波峰波谷识别**:遍历数组,确定每个波峰和波谷的位置。
3. **排序与处理**:将波峰波谷按高度降序排序,并依次处理,确保正确计算每种情况下的部分数量。
4. **二分查找**:使用二分查找算法快速定位特定高度对应的答案。

### 代码示例
```cpp
#include
#include
#define MAX 1000000+10
using namespace std;

int h[MAX];
int Q[MAX];
int res[MAX];
struct Node {
int height;
bool isPeak;
};

bool compare(Node a, Node b) {
return a.height > b.height;
}

int binarySearch(Node a[], int len, int target) {
int left = 0, right = len - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (a[mid].height == target) return mid;
else if (a[mid].height else left = mid + 1;
}
return right;
}

int main() {
int T;
cin >> T;
for (int cas = 1; cas <= T; ++cas) {
int n, m;
cin >> n >> m;
h[0] = h[n + 1] = -1;
for (int i = 1; i <= n; ++i) cin >> h[i];

vector peaksAndValleys;
for (int i = 1; i <= n; ++i) {
if ((h[i] > h[i - 1] && h[i] > h[i + 1]) || (h[i] peaksAndValleys.push_back({h[i], h[i] > h[i - 1]});
}
}

sort(peaksAndValleys.begin(), peaksAndValleys.end(), compare);
int currentParts = 1;
for (const auto& point : peaksAndValleys) {
if (point.isPeak) --currentParts;
else ++currentParts;
res[point.height] = currentParts;
}

cout <<"Case #" < for (int i = 0; i int query;
cin >> query;
int index = binarySearch(peaksAndValleys.data(), peaksAndValleys.size(), query);
cout <<(index >= 0 ? res[peaksAndValleys[index].height] : 0) <<' ';
}
cout < }
return 0;
}
```
### 结论
通过上述方法,我们可以高效地解决Disappearing Blocks问题,利用离散化和二分查找技术,确保了算法的效率和准确性。
推荐阅读
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本题探讨了一种字符串变换方法,旨在判断两个给定的字符串是否可以通过特定的字母替换和位置交换操作相互转换。核心在于找到这些变换中的不变量,从而确定转换的可能性。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • Codeforces Round #566 (Div. 2) A~F个人题解
    Dashboard-CodeforcesRound#566(Div.2)-CodeforcesA.FillingShapes题意:给你一个的表格,你 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 本题涉及一棵由N个节点组成的树(共有N-1条边),初始时所有节点均为白色。题目要求处理两种操作:一是改变某个节点的颜色(从白变黑或从黑变白);二是查询从根节点到指定节点路径上的第一个黑色节点,若无则输出-1。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文介绍如何利用动态规划算法解决经典的0-1背包问题。通过具体实例和代码实现,详细解释了在给定容量的背包中选择若干物品以最大化总价值的过程。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • This document outlines the recommended naming conventions for HTML attributes in Fast Components, focusing on readability and consistency with existing standards. ... [详细]
  • C++: 实现基于类的四面体体积计算
    本文介绍如何使用C++编程语言,通过定义类和方法来计算由四个三维坐标点构成的四面体体积。文中详细解释了四面体体积的数学公式,并提供了两种不同的实现方式。 ... [详细]
author-avatar
C3calm_daidai_649
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有