湘大头歌程-Ride to Office练习笔记

题目描述

起点与终点相隔 4500 米。现 Charley 需要从起点骑车到终点。但是,他有个习惯,沿途需要有人陪伴,即以相同的速度, 与另外一个人一起骑。而当他遇到以更快的速度骑车的人时,他会以相应的速度跟上这个更快的人。先给定所有与 Charley 同路的人各自的速度与出发时间,问 Charley 以这种方式跟人,骑完 4500 米需要多少时间。得出的结果若是小数,则向上取整。

输入输出格式

输入格式

输入若干组数据,每组数据第一行 n, n 为 0,表示输入结束,接着输入 n 行数据,每行 2 个数据,表示速度 v 和出发时间 t ,如果 t<0,表示陪伴人提早出发了。

输出格式

输出对应若干行数据,每行输出 1 个数,表示最快到达的时间。

输入输出样例1

输入

4

20 0

25 -155

27 190

30 240

2

21 0

22 34

0

输出

780

771

说明提示

1≤n≤10000

初始代码

答案错误

cs 复制代码
//从比上一次速度大的人中找能碰上C的最短时间,即找C下次变化的速度
#include<stdio.h>
#include<stdlib.h>
double cnt(double v_C, double v_other, double s_other, double s_C, double t_before)
{
    double t_may = (s_other + s_C - t_before * v_other) / v_other - v_C;
    return t_may;
}
typedef struct other {
    double v;double t;double s;
}other;
int compare(const void* a, const void* b)
{
    double diff = ((other*)a)->v - ((other*)b)->v;
    if (diff > 0) return 1;
    if (diff < 0) return -1;
    return 0;
}
int main()
{
    int n;
    while (scanf("%d", &n) == 1)
    {
        if (n == 0)
            break;
        double v = 0.0, t_before = 0.0, s = 0.0;
        other o[10000] = { 0.0,0.0,0.0 };
        int m = 0;
        for (int i = 0;i < n;i++)
        {
            int a, b;
            scanf("%d %d", &a, &b);
            if (b == 0)//初始化起点最大速度(如果有0时刻出发的)
            {
                if ((double)a > v)
                    v = (double)a;
            }
            //提早出发的人要么赶不上,要么赶上时速度比他大,即不变速
            if (b > 0)
            {
                o[m].v = (double)a;
                o[m].t = (double)b;
                o[m].s = o[m].t * o[m].v;
                m++;
            }
        }
        qsort(o, m, sizeof(other), compare);//按速度升序排序
        int n_v = 0;
        for (int i = 0;i < m;i++)
        {
            if (o[i].v > v)//找比之前速度大的速度
            {
                n_v = i;
                break;
            }
        }
        double t_diff[10000] = { 0.0 };
        while (s <= 4500.0)
        {
            double min_t = 5000, v_copy = v, s_copy = s, t_copy = t_before;
            for (int i = n_v;i < m;i++)
            {
                double  t = cnt(v_copy, o[i].v, o[i].s, s_copy, t_copy);
                if (min_t > t)//改变速度为最先能与C同路的人的速度
                {
                    min_t = t;
                    v = o[i].v;
                    t_before = t_copy + min_t;
                    s = s_copy + v_copy * min_t;
                    n_v = i;
                }
            }
            if (s > 4500)
            {
                t_before = t_copy + (4500 - s_copy) / v_copy;
            }
        }
        int t_result = (int)t_before + 1;
        printf("%d\n", t_result);
    }
    return 0;
}

反思问题

一开始想通过模拟算法,计算Charley从起点到终点的整个变速过程,进而得到时间。忽略了可从

Charley最后会与一人同时到达终点的角度思考。

题目理解的关键点

Charley 的规则

  • 必须有人陪伴(同速骑行)

  • 遇到更快的人就加速跟上

  • 出发时间是 0

关键推理

  • 如果 Charley 最终和某人同时到达终点,那么他的到达时间就是那个人的到达时间

  • 他会在路上遇到不同的人并加速,但最终会跟着最快的人到达

  • 对于 t < 0 的人(提前出发),Charley 在起点无法和他们一起出发,所以不考虑

最终AC代码

cs 复制代码
#include <stdio.h>
#include <math.h>
#include <limits.h>

int main() {
    int n;
    while (scanf("%d", &n) == 1 && n != 0) {
        int ans = INT_MAX;
        for (int i = 0; i < n; i++) {
            int v, t;
            scanf("%d %d", &v, &t);
            if (t < 0) continue;
            // 路程 4.5 km, v km/h
            // 时间 = t + 4.5 / v * 3600 秒
            int time = t + (int)ceil(4.5 / v * 3600);
            if (time < ans) ans = time;
        }
        printf("%d\n", ans);
    }
    return 0;
}

函数拓展

一、limits.h 头文件

1. 作用

定义各种整数类型的极限值常量

2. 主要常量

常量 含义 典型值
INT_MAX int 最大值 2147483647
INT_MIN int 最小值 -2147483648
UINT_MAX unsigned int 最大值 4294967295
LONG_MAX long 最大值 2147483647
CHAR_BIT 一个字节的位数 8
CHAR_MAX char 最大值 127
SCHAR_MAX signed char 最大值 127
SCHAR_MIN signed char 最小值 -128

3. 使用示例

cs 复制代码
#include <stdio.h>
#include <limits.h>

int main() {
    printf("INT_MAX = %d\n", INT_MAX);
    printf("INT_MIN = %d\n", INT_MIN);
    
    int ans = INT_MAX;  // 常用作最小值查找的初始值
    return 0;
}

4. 应用场景

  • 初始化变量为最大值/最小值

  • 边界检查

  • 溢出检测


二、math.h 中的取整函数

1. 函数概览

函数 功能 原型
ceil() 向上取整 double ceil(double x)
floor() 向下取整 double floor(double x)
round() 四舍五入 double round(double x)
trunc() 向零取整 double trunc(double x)

2. 详细说明

ceil() - 向上取整
复制代码
#include <math.h>
double ceil(double x);  // 返回 ≥ x 的最小整数

示例

复制代码
ceil(2.3) = 3.0
ceil(2.7) = 3.0
ceil(-2.3) = -2.0
ceil(-2.7) = -2.0
floor() - 向下取整
复制代码
#include <math.h>
double floor(double x);  // 返回 ≤ x 的最大整数

示例

复制代码
floor(2.3) = 2.0
floor(2.7) = 2.0
floor(-2.3) = -3.0
floor(-2.7) = -3.0
round() - 四舍五入
复制代码
#include <math.h>
double round(double x);  // 返回最接近的整数

示例

复制代码
round(2.3) = 2.0
round(2.7) = 3.0
round(2.5) = 3.0
round(-2.3) = -2.0
round(-2.7) = -3.0
round(-2.5) = -3.0
trunc() - 向零取整
复制代码
#include <math.h>
double trunc(double x);  // 去掉小数部分

示例

复制代码
trunc(2.3) = 2.0
trunc(2.7) = 2.0
trunc(-2.3) = -2.0
trunc(-2.7) = -2.0

3. 对比表格

数值 ceil floor round trunc
2.3 3.0 2.0 2.0 2.0
2.7 3.0 2.0 3.0 2.0
-2.3 -2.0 -3.0 -2.0 -2.0
-2.7 -2.0 -3.0 -3.0 -2.0
相关推荐
嵌入小生00711 分钟前
标准IO---核心函数接口延续(嵌入式Linux)
c语言·vscode·vim·嵌入式·小白·标准io·函数接口
A尘埃11 分钟前
超市购物篮关联分析与货架优化(Apriori算法)
算法
.小墨迹18 分钟前
apollo学习之借道超车的速度规划
linux·c++·学习·算法·ubuntu
数智工坊20 分钟前
【数据结构-树与二叉树】4.3 二叉树的存储结构
数据结构
独好紫罗兰26 分钟前
对python的再认识-基于数据结构进行-a004-列表-实用事务
开发语言·数据结构·python
不穿格子的程序员28 分钟前
从零开始刷算法——贪心篇1:跳跃游戏1 + 跳跃游戏2
算法·游戏·贪心
大江东去浪淘尽千古风流人物31 分钟前
【SLAM新范式】几何主导=》几何+学习+语义+高效表示的融合
深度学习·算法·slam
山岚的运维笔记32 分钟前
SQL Server笔记 -- 第20章:TRY/CATCH
java·数据库·笔记·sql·microsoft·sqlserver
Gain_chance34 分钟前
33-学习笔记尚硅谷数仓搭建-DWS层交易域用户粒度订单表分析及设计代码
数据库·数据仓库·hive·笔记·学习·datagrip
铉铉这波能秀39 分钟前
LeetCode Hot100数据结构背景知识之列表(List)Python2026新版
数据结构·leetcode·list