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;
}
相关推荐
liminla!1 分钟前
SQL 从入门到进阶:语法速查与实战练习(完整优化版)
数据库·sql·算法
沫璃染墨1 小时前
从零入门计算机网络系列(十一):HTTP协议进阶——从重定向原理到GET/POST与Fiddler抓包
linux·服务器·开发语言·网络·c++·tcp/ip·html
维克兜率天1 小时前
【维克】指数调整:哪些股票会被“强制买入“?
人工智能·python·算法
罗西的思考2 小时前
【轻量化复刻大模型】线性注意力交互式演示
人工智能·算法·机器学习
神也畏惧菠萝2 小时前
Day08 Python流程控制从入门到上瘾:if/match/while/for四件套,从B站登录一路打到猜数字游戏
python·算法·数据存储·for·while·if·ifelse
揽星河..2 小时前
【C语言】分支和循环
c语言·c++·算法
Fuyo_11194 小时前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法
jktantan4 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
揽星河..4 小时前
【C语言】猜数字游戏
c语言·算法·游戏