PTA基础编程题目集 7-17 爬动的蠕虫(C语言实现)

摘要

本文描述了一个经典的"蠕虫爬井"模拟问题。蠕虫从井底(高度为0)开始,每分钟上爬 U 寸,随后必须休息一分钟,期间下滑 D 寸(D < U)。题目要求计算蠕虫头部到达井口(深度 N 寸)所需的总时间(分钟),并规定不足一分钟按一分钟计,且一旦在上爬过程中到达井口即视为完成。

输入为三个正整数 N、U、D(N ≤ 100),输出为总时间。文中提供了完整的 C 语言实现代码,采用直接模拟的算法,并附有详细的行内注释。算法核心是循环模拟上爬与下滑过程,时间复杂度为 O(N/(U-D)),同时总结了边界条件、时间计数等关键注意事项。

题目描述

一条蠕虫长1寸,在一口深为 N 寸的井的底部。已知蠕虫每1分钟可以向上爬 U 寸,但必须休息1分钟才能接着往上爬。在休息的过程中,蠕虫又下滑了 D 寸。就这样,上爬和下滑重复进行。请问,蠕虫需要多长时间才能爬出井?

这里要求不足1分钟按1分钟计,并且假定只要在某次上爬过程中蠕虫的头部到达了井的顶部,那么蠕虫就完成任务了。初始时,蠕虫是趴在井底的(即高度为0)。

输入格式:

输入在一行中顺序给出3 个正整数 N、U、D,其中D<U,N不超过100。

输出格式:

在一行中输出蠕虫爬出井的时间,以分钟为单位。

输入样例:

复制代码
12 3 1

输出样例:

复制代码
11

代码部分实现

c 复制代码
#include <stdio.h>

int main(void)
{
    // 变量定义
    int N, U, D, time = 0, height = 0; // N: 井深,U: 每分钟上爬距离,D: 每分钟下滑距离,time: 累计时间,height: 当前高度
    scanf("%d %d %d", &N, &U, &D);      // 读取输入的三个正整数 N, U, D
    
    // 模拟蠕虫爬井过程
    while (1) {
        time++;          // 上爬花费1分钟
        height += U;     // 上爬 U 寸
        if (height >= N) { // 判断是否到达或超过井口
            break;       // 到达井口,跳出循环
        }
        
        time++;          // 下滑前休息1分钟(计入总时间)
        height -= D;     // 下滑 D 寸
    }
    
    printf("%d\n", time); // 输出总时间
    return 0;
}

算法流程图

下面是蠕虫爬井算法的流程图,展示了程序的执行逻辑:
#mermaid-svg-h8BKQMNhEczvdPLn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-h8BKQMNhEczvdPLn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-h8BKQMNhEczvdPLn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-h8BKQMNhEczvdPLn .error-icon{fill:#552222;}#mermaid-svg-h8BKQMNhEczvdPLn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-h8BKQMNhEczvdPLn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-h8BKQMNhEczvdPLn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-h8BKQMNhEczvdPLn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-h8BKQMNhEczvdPLn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-h8BKQMNhEczvdPLn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-h8BKQMNhEczvdPLn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-h8BKQMNhEczvdPLn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-h8BKQMNhEczvdPLn .marker.cross{stroke:#333333;}#mermaid-svg-h8BKQMNhEczvdPLn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-h8BKQMNhEczvdPLn p{margin:0;}#mermaid-svg-h8BKQMNhEczvdPLn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-h8BKQMNhEczvdPLn .cluster-label text{fill:#333;}#mermaid-svg-h8BKQMNhEczvdPLn .cluster-label span{color:#333;}#mermaid-svg-h8BKQMNhEczvdPLn .cluster-label span p{background-color:transparent;}#mermaid-svg-h8BKQMNhEczvdPLn .label text,#mermaid-svg-h8BKQMNhEczvdPLn span{fill:#333;color:#333;}#mermaid-svg-h8BKQMNhEczvdPLn .node rect,#mermaid-svg-h8BKQMNhEczvdPLn .node circle,#mermaid-svg-h8BKQMNhEczvdPLn .node ellipse,#mermaid-svg-h8BKQMNhEczvdPLn .node polygon,#mermaid-svg-h8BKQMNhEczvdPLn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-h8BKQMNhEczvdPLn .rough-node .label text,#mermaid-svg-h8BKQMNhEczvdPLn .node .label text,#mermaid-svg-h8BKQMNhEczvdPLn .image-shape .label,#mermaid-svg-h8BKQMNhEczvdPLn .icon-shape .label{text-anchor:middle;}#mermaid-svg-h8BKQMNhEczvdPLn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-h8BKQMNhEczvdPLn .rough-node .label,#mermaid-svg-h8BKQMNhEczvdPLn .node .label,#mermaid-svg-h8BKQMNhEczvdPLn .image-shape .label,#mermaid-svg-h8BKQMNhEczvdPLn .icon-shape .label{text-align:center;}#mermaid-svg-h8BKQMNhEczvdPLn .node.clickable{cursor:pointer;}#mermaid-svg-h8BKQMNhEczvdPLn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-h8BKQMNhEczvdPLn .arrowheadPath{fill:#333333;}#mermaid-svg-h8BKQMNhEczvdPLn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-h8BKQMNhEczvdPLn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-h8BKQMNhEczvdPLn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-h8BKQMNhEczvdPLn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-h8BKQMNhEczvdPLn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-h8BKQMNhEczvdPLn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-h8BKQMNhEczvdPLn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-h8BKQMNhEczvdPLn .cluster text{fill:#333;}#mermaid-svg-h8BKQMNhEczvdPLn .cluster span{color:#333;}#mermaid-svg-h8BKQMNhEczvdPLn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-h8BKQMNhEczvdPLn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-h8BKQMNhEczvdPLn rect.text{fill:none;stroke-width:0;}#mermaid-svg-h8BKQMNhEczvdPLn .icon-shape,#mermaid-svg-h8BKQMNhEczvdPLn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-h8BKQMNhEczvdPLn .icon-shape p,#mermaid-svg-h8BKQMNhEczvdPLn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-h8BKQMNhEczvdPLn .icon-shape .label rect,#mermaid-svg-h8BKQMNhEczvdPLn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-h8BKQMNhEczvdPLn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-h8BKQMNhEczvdPLn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-h8BKQMNhEczvdPLn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

开始
初始化

time = 0, height = 0
读取输入 N, U, D
循环开始
上爬阶段

time++

height += U
height >= N?
输出 time

程序结束
休息/下滑阶段

time++

height -= D
结束

该流程图清晰地展示了:

  1. 初始化阶段:设置时间和高度为0
  2. 输入读取:获取井深N、上爬距离U、下滑距离D
  3. 循环模拟
    • 上爬阶段:时间增加1分钟,高度增加U寸
    • 判断是否到达井口:如果高度≥井深,则跳出循环输出结果
    • 下滑阶段:时间再增加1分钟,高度减少D寸
  4. 循环继续:返回循环开始,继续下一轮上爬

算法总结

核心思想

本算法采用模拟 方法,逐分钟模拟蠕虫的上爬与下滑过程。每次循环代表一个"上爬+下滑"的完整周期(实际为两分钟),通过累加时间 time 和更新高度 height,直到高度 height 达到或超过井深 N 时停止。

时间复杂度

  • 最坏情况下,蠕虫需要爬行接近井深的高度,循环次数与井深 N 和爬升净增量 (U - D) 相关。
  • 每次循环执行常数次操作,因此时间复杂度为 O(N / (U - D)),即线性级别。
  • 由于题目限制 N ≤ 100,该算法在常数时间内即可完成。

注意事项

  1. 边界条件 :循环中使用 height >= N 作为终止条件,确保蠕虫在上爬过程中头部到达井口即完成任务,符合题目要求。
  2. 时间计数 :每次上爬和下滑均计为 1 分钟,且 time 在循环开始时即自增,保证了"不足 1 分钟按 1 分钟计"的约定。
  3. 输入保证 :题目已给定 D < U,因此蠕虫每两个分钟净上升 U - D 寸,保证最终能够爬出井。
  4. 变量初始化timeheight 初始化为 0,对应蠕虫从井底开始。
  5. 代码简洁性 :使用 while (1) 无限循环配合 break,使逻辑清晰易读。
相关推荐
2401_862880828 小时前
数据结构 --- 栈
c语言·数据结构·算法
萧瑟余晖8 小时前
Java深入解析篇三十六之分布式系统详解
java·开发语言·分布式
致Great8 小时前
Qwen3.8-27B 接入 DSH 全流程实测:写代码、跑长任务,都没问题
算法
ZJU_统一阿萨姆9 小时前
【推理优化进阶】调度器的数学内核:排队论、SLO 与在线决策
开发语言·人工智能·语言模型·系统架构·vllm
Tisfy9 小时前
LeetCode 3471.找出最大的几近缺失整数:三种情况判断
算法·leetcode·题解·分类讨论
SomeB1oody9 小时前
【RustyML入门】5.2. 分类指标
开发语言·后端·机器学习·rust·教程
linux-hzh10 小时前
百日算法修炼 · Day 12
算法·深度优先
ZJU_统一阿萨姆10 小时前
【推理优化进阶】图编译与运行时:动态形状、CUDA Graph 与内存规划
开发语言·人工智能·语言模型·架构·开源
@呱呱爱学习10 小时前
C++大成之路_ STL容器_ Vector
开发语言·c++
额额额对了10 小时前
数据结构:二叉树
c语言·数据结构·算法