UVA-1442 洞穴 题解答案代码 算法竞赛入门经典第二版

GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版

还是使用算法竞赛入门经典书中的方式,O(n)的时间即可得到结果。但书中写的并不清楚,他只说了往左延伸和右延伸。

实际上需要遍历两次,第一次是从左到右,第二次从右到左。从左到右的时候,第一个元素直接设置为最高水位(天花板)。遍历时,当前元素只考虑前一个元素对其造成的影响。我选择了分每一种细节情况讨论,即前一个天花板地板,当前天花板地板的不同位置关系下,以及前一个水位是多少时,当前水位应该是多少。

从右到左遍历时也是一样,考虑后一个元素对当前元素的影响,分每种情况细节讨论。但是这里要简单一些,因为后一个水位不会比当前水位高(我们左侧遍历时考虑了这一点),因此只需要考虑后一个元素水位更低的场景。

AC代码

cpp 复制代码
#include <stdio.h>
#define MAXN 1000005

int arrFloor[MAXN];   // 地板
int arrCeiling[MAXN]; // 天花板
int arrValue[MAXN];   // 当前水位
int n;

void computedFront()
{
  int i;
  arrValue[0] = arrCeiling[0];
  for (i = 1; i < n; ++i)
  {
    if (arrCeiling[i] <= arrFloor[i - 1])
    {
      arrValue[i] = arrCeiling[i];
      continue;
    }
    if (arrCeiling[i] >= arrFloor[i - 1] && arrCeiling[i] <= arrCeiling[i - 1] && arrFloor[i] <= arrFloor[i - 1])
    {
      if (arrCeiling[i] <= arrValue[i - 1])
        arrValue[i] = arrCeiling[i];
      else
        arrValue[i] = arrValue[i - 1];
      continue;
    }
    if (arrCeiling[i] <= arrCeiling[i - 1] && arrFloor[i] >= arrFloor[i - 1])
    {
      if (arrCeiling[i] <= arrValue[i - 1])
        arrValue[i] = arrCeiling[i];
      else if (arrFloor[i] <= arrValue[i - 1])
        arrValue[i] = arrValue[i - 1];
      else
        arrValue[i] = arrFloor[i];
      continue;
    }
    if (arrCeiling[i] >= arrCeiling[i - 1] && arrFloor[i] >= arrFloor[i - 1] && arrFloor[i] <= arrCeiling[i - 1])
    {
      if (arrFloor[i] <= arrValue[i - 1])
        arrValue[i] = arrValue[i - 1];
      else
        arrValue[i] = arrFloor[i];
      continue;
    }
    if (arrFloor[i] >= arrCeiling[i - 1])
    {
      arrValue[i] = arrFloor[i];
      continue;
    }
    if (arrFloor[i] <= arrFloor[i - 1] && arrCeiling[i] >= arrCeiling[i - 1])
    {
      if (arrFloor[i] <= arrValue[i - 1])
        arrValue[i] = arrValue[i - 1];
      else
        arrValue[i] = arrFloor[i];
      continue;
    }
    // arrValue[i] = arrValue[i - 1];
  }
}

void computedBack()
{
  int i;
  for (i = n - 2; i >= 0; --i)
  {
    if (arrCeiling[i] <= arrFloor[i + 1])
      continue;
    if (arrCeiling[i] >= arrFloor[i + 1] && arrCeiling[i] <= arrCeiling[i + 1] && arrFloor[i] <= arrFloor[i + 1])
    {
      if (arrValue[i + 1] <= arrValue[i])
        arrValue[i] = arrValue[i + 1];
      continue;
    }
    if (arrCeiling[i] <= arrCeiling[i + 1] && arrFloor[i] >= arrFloor[i + 1])
    {
      if (arrValue[i + 1] <= arrValue[i])
        arrValue[i] = arrValue[i + 1] > arrFloor[i] ? arrValue[i + 1] : arrFloor[i];
      continue;
    }
    if (arrCeiling[i] >= arrCeiling[i + 1] && arrFloor[i] >= arrFloor[i + 1] && arrFloor[i] <= arrCeiling[i + 1])
    {
      if (arrValue[i + 1] <= arrValue[i])
        arrValue[i] = arrValue[i + 1] > arrFloor[i] ? arrValue[i + 1] : arrFloor[i];
      continue;
    }
    if (arrFloor[i] >= arrCeiling[i + 1])
    {
      arrValue[i] = arrFloor[i];
      continue;
    }
    if (arrFloor[i] <= arrFloor[i + 1] && arrCeiling[i] >= arrCeiling[i + 1])
    {
      if (arrValue[i + 1] <= arrValue[i])
        arrValue[i] = arrValue[i + 1];
      continue;
    }
  }
}

int main()
{
  int z, i;
  long long sum;
  scanf("%d", &z);
  while (z--)
  {
    scanf("%d", &n);
    for (i = 0; i < n; ++i)
      scanf("%d", &arrFloor[i]);
    for (i = 0; i < n; ++i)
      scanf("%d", &arrCeiling[i]);
    computedFront();
    computedBack();
    sum = 0;
    for (i = 0; i < n; ++i)
    {
      sum += arrValue[i] - arrFloor[i];
    }
    printf("%lld\n", sum);
  }

  return 0;
}
相关推荐
朽棘不雕1 小时前
进一步了解模板
c++
叠层归一研究院2 小时前
基于极限自指的叠层归一宇宙结构理论——无元外部封闭系统的内生区分模型
人工智能·经验分享·算法·agi
Selvaggia3 小时前
Diffusion Model 的基本原理与模型架构
算法
汉克老师4 小时前
CSP-J 2026 初赛试题解析(第一部分:选择题(8-15))精讲
c++·csp-j·小学生·学c++编程
wabs6664 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
hanlin034 小时前
刷题笔记:力扣第41题-缺失的第一个正数
笔记·算法·leetcode
shehuiyuelaiyuehao5 小时前
算法50,分治归并,数组中的逆序对
java·算法
风合星语5 小时前
2026 ROS 2 Lyrical C++ 入门(五):Action 实战——任务反馈、取消与超时处理
c++·机器人·ros2·异步编程·lyrical
阳明山水5 小时前
校准分位数驱动智能库存决策
人工智能·深度学习·算法·机器学习·架构