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;
}
相关推荐
y1su8 分钟前
Leetcode 二分模板
java·数据结构·算法·leetcode·排序算法
youshi666815 分钟前
平衡车——PID算法优化
stm32·单片机·嵌入式硬件·算法·pid·平衡车
无名猿33 分钟前
constexpr 能力扩张:从 C++11 到 C++20 的编译期计算
c++·性能优化·现代c++·编译期
007张三丰33 分钟前
C/C++ 内存管理详解:从内存分布到 new/delete 底层原理
java·c语言·c++·内存管理
聪明蛋子哟1 小时前
不仅仅是向量检索:结合知识图谱与Tool Calling的混合增强生成(Hybrid RAG)方案
人工智能·算法·知识图谱
Pniubi1 小时前
力扣55跳跃游戏(贪心)
算法·leetcode·游戏
三月微暖寻春笋1 小时前
【和春笋一起学C++】(七十二)类模板
开发语言·c++·实例·类模板·使用类模板·数组模板
xlq223221 小时前
全面复习4
c++
jyyyx的算法博客2 小时前
传球游戏【思维】
算法
FL16238631292 小时前
关于2026年南昌大学811信号与系统最后一题电路系统解题思路
算法