Julián Álvarez 2023-10-28 15:06 采纳率: 50%
浏览 23
已结题

2023Csp-J T2公路

2023CSP-J 复赛T2 公路:

为什么我写出来在洛谷上只有15分?

#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int n,d,i,a[N],v[N];
long long q,ans,distmp;
//我这里a数组表示距离,v数组表示油价,和原题正好相反 
int main() {
    scanf("%d%d",&n,&d);
    for(i=1;i<n;i++)
        scanf("%d",&a[i]);
    for(i=1;i<=n;i++)
        scanf("%d",&v[i]);
    for(i=2;i<=n;i++) 
        if(v[i]>v[i-1])
            v[i]=v[i-1];
    for(i=1;i<n;i++) {
        int dis=a[i]-distmp;
        if(dis<=0) {
            distmp=-dis;
            continue;
        }
        if(dis%d==0) 
            q=dis/d;
        else q=dis/d+1;
        ans+=q*v[i];
        distmp=q*d-a[i];
    }
    printf("%lld",ans);
    return 0;
} 

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-28 17:20
    关注

    【以下回答由 GPT 生成】

    首先,让我们来分析一下给定的代码并找出问题所在。

    代码中使用了一个循环来读取输入的数据,并将其存储在数组 a[]v[] 中。然后使用另一个循环来依次处理每个公路段,并计算最终得分。在处理每个公路段时,首先计算当前公路段的长度 dis,然后根据长度计算所需的施工个数 q。根据题目要求,如果 dis 不能被 d 整除,需要向上取整。然后根据施工个数 q 和公路段的修建难度得出当前公路段的得分,并更新总得分 ans。最后,更新 distmp 用于下一个公路段的处理。

    一开始没有明显的错误,让我们编译和运行一下代码,输入一些测试数据,看看是否有行为异常。

    然后,我们可以仔细检查代码中每一部分的逻辑,看看是否有地方可能出现问题。以下是一些可能的问题点:

    1. 输入数据的读取:我们需要确保输入数据的格式和范围与题目要求一致。现在的代码中使用 scanf 函数来读取数据,但没有对输入的格式进行校验。我们可以添加一些代码来检查输入数据的范围和格式是否正确。

    2. 数组边界:数组 a[]v[] 的长度都为 N=100005,但公路段的个数 n 可能会小于 N。因此,在循环中访问数组元素时需要确保不超出数组边界。

    3. 公路段长度计算:计算公路段长度时,使用了一个变量 distmp 来记录前一个公路段施工结束后剩余的长度。但在计算当前公路段长度时,公式 dis = a[i] - distmp 可能会出现问题。我们需要确保 distmp 是前一个公路段施工结束后剩余的正整数长度。

    4. 得分计算:根据题目要求,需要计算每个公路段的施工个数,并根据施工个数和公路段的修建难度得出得分。在现有代码中,施工个数的计算和得分的计算都是基于施工长度 dis 来进行的,我们需要确保这部分计算是正确的。

    接下来,让我们通过逐步分析代码来找出问题所在。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 100005;
    int n, d, i, a[N], v[N];
    long long q, ans, distmp;
    
    int main() {
        scanf("%d%d", &n, &d);
        for(i=1; i<n; i++) {
            scanf("%d", &a[i]);
        }
        for(i=1; i<=n; i++) {
            scanf("%d", &v[i]);
        }
        for(i=2; i<=n; i++) {
            if(v[i] > v[i-1])
                v[i] = v[i-1];
        }
        for(i=1; i<n; i++) {
            int dis = a[i] - distmp;
            if(dis <= 0) {
                distmp = -dis;
                continue;
            }
            if(dis % d == 0) 
                q = dis / d;
            else 
                q = dis / d + 1;
            ans += q * v[i];
            distmp = q * d - a[i];
        }
        printf("%lld", ans);
        return 0;
    }
    

    首先,我们来检查输入数据的读取部分。

    scanf("%d%d", &n, &d);
    for(i=1; i<n; i++) {
        scanf("%d", &a[i]);
    }
    for(i=1; i<=n; i++) {
        scanf("%d", &v[i]);
    }
    

    我们假设输入的数据满足题目给定的范围要求。但是,有一个问题是 a[]v[] 数组的下标范围是 1 到 n,而不是 0 到 n-1。因此,我们需要将循环的起始下标改为 1。

    修改后的代码如下:

    scanf("%d%d", &n, &d);
    for(i=1; i<=n; i++) {
        scanf("%d", &a[i]);
    }
    for(i=1; i<=n; i++) {
        scanf("%d", &v[i]);
    }
    

    接下来,我们来检查循环中数组的边界问题。

    for(i=2; i<=n; i++) {
        if(v[i] > v[i-1])
            v[i] = v[i-1];
    }
    

    循环中的下标范围是 2 到 n,这是正确的。因此,这部分代码没有问题。

    接下来,我们来检查公路段长度的计算。

    for(i=1; i<n; i++) {
        int dis = a[i] - distmp;
        if(dis <= 0) {
            distmp = -dis;
            continue;
        }
        if(dis % d == 0) 
            q = dis / d;
        else 
            q = dis / d + 1;
        ans += q * v[i];
        distmp = q * d - a[i];
    }
    

    这部分代码用于计算每个公路段的长度 dis,并根据长度计算施工个数 q 和得分 ans。在计算长度时,代码使用了变量 distmp 来记录前一个公路段施工结束后剩余的长度。但是,在计算长度之前,需要根据公式 distmp = q * d - a[i] 更新 distmp 的值。我们发现这个更新操作在循环的末尾,而不是在计算长度之前。因此,当前公路段的长度 dis 是错误的。

    为了解决这个问题,我们需要在计算长度之前更新 distmp 的值。

    修改后的代码如下:

    for(i=1; i<n; i++) {
        distmp = q * d - a[i];
        int dis = a[i] - distmp;
        if(dis <= 0) {
            distmp = -dis;
            continue;
        }
        if(dis % d == 0) 
            q = dis / d;
        else 
            q = dis / d + 1;
        ans += q * v[i];
    }
    

    最后,我们来检查得分的计算。

    if(dis % d == 0) 
        q = dis / d;
    else 
        q = dis / d + 1;
    ans += q * v[i];
    

    根据题目要求,当 dis 不能被 d 整除时,需要向上取整。但是,我们发现这部分计算直接使用了除法和加法操作,而没有进行取整操作。因此,我们需要添加一个取整操作来确保得分的计算是正确的。

    修改后的代码如下:

    if(dis % d == 0) 
        q = dis / d;
    else 
        q = dis / d + 1;
    ans += ceil(q) * v[i];
    

    现在,让我们重新编译和运行代码,输入一些测试数据,看看是否有行为异常。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 11月15日
  • 创建了问题 10月28日

悬赏问题

  • ¥15 opencv图像处理,需要四个处理结果图
  • ¥15 无线移动边缘计算系统中的系统模型
  • ¥15 深度学习中的画图问题
  • ¥15 java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条
  • ¥15 Python报错怎么解决
  • ¥15 simulink如何调用DLL文件
  • ¥15 关于用pyqt6的项目开发该怎么把前段后端和业务层分离
  • ¥30 线性代数的问题,我真的忘了线代的知识了
  • ¥15 有谁能够把华为matebook e 高通骁龙850刷成安卓系统,或者安装安卓系统
  • ¥188 需要修改一个工具,懂得汇编的人来。