[数形结合] UVa1451 Averange 平均值 (前缀和+斜率优化)(单调栈)

本文分享了一种解决区间最大平均数问题的高效算法实现,通过预处理和双指针技巧,避免了直接使用除法带来的精度问题,实现了快速查找区间内的最大平均数值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

这里写图片描述

思路

这里写图片描述
这里写图片描述
这里写图片描述

代码

#include <cstdio>
#include <cstdlib>

const int maxn = 100000 + 1000;
int num[maxn], sum[maxn], n, L, p[maxn];
char s[maxn];

// 有效避免除法
int cmp(int x1, int x2, int x3, int x4) {
    return (sum[x2] - sum[x1 - 1]) * (x4 - x3 + 1) - (sum[x4] - sum[x3 - 1]) * (x2 - x1 + 1);
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        scanf("%d%d%s", &n, &L, s + 1);
        for (int i = 1; i <= n; i++) num[i] = s[i] - '0';
        sum[0] = 0;
        for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + num[i];

        int ansL = 1, ansR = L, i = 0, j = 0;
        for (int t = L; t <= n; t++) {
            while (i < j - 1 && cmp(p[j - 2], p[j - 1], p[j - 1], t - L) > 0) j--;
            p[j++] = t - L + 1;
            while (i < j - 1 && cmp(p[i + 1], t, p[i], t) >= 0) i++;
            int c = cmp(p[i], t, ansL, ansR);
            if (c > 0 || (c == 0 && t - p[i] < ansR - ansL)) {
                ansL = p[i];
                ansR = t;
            }
        }

        printf("%d %d\n", ansL, ansR);
    }
    return 0;
}

感悟

1.此题虐我千百遍,我仍待此题如初恋。。
2.折磨了我将近半个月,思路那是相当清晰,但就是调不出来,跟udebug上数据一对比,总有各种各样的错误,干脆拿来LRJ的算了。自我感觉这道题理解地够清晰了。
3.也算烂尾吧。。比较有关形的题基本没做过,一上来就做这种难度的,调不出来也是没办法。

<think>好的,用户让我介绍一下如何在PTA上用C语言求整数均值。我需要先明确题目的具体要求。通常,PTA的题目会有明确的输入输出格式,所以得先确认用户的问题是否是关于如何读取四个整数,计算它们的平均值,并按照指定格式输出。 首先,我应该考虑如何获取四个整数。在C语言中,常用的方法是使用scanf函数读取用户输入。这里需要注意输入的格式,题目是否有指定分隔符,比如空格还是换行。假设题目要求四个整数用空格分隔,那么代码里应该用scanf("%d %d %d %d", &a, &b, &c, &d)这样的形式。 接下来计算总和和平均值。总和的话,直接把四个数相加即可。平均值需要注意数据类型的问题,因为整数相除会得到整数,但题目可能要求输出浮点数。例如,如果平均值是小数,应该将总和转换为浮点型再进行除法运算,比如用(float)sum / 4。不过,题目是否要求四舍五入或者保留小数位数呢?通常PTA题目会给出具体要求,比如输出一位小数,这时候需要用%.1f来格式化输出。 然后,输出格式也是关键。题目可能要求输出总和和平均值,中间用空格分隔,或者特定格式。例如,输出语句可能是printf("Sum = %d; Average = %.1f", sum, average)。需要严格按照题目要求的格式,包括空格、分号等符号,否则PTA可能会判错。 再考虑可能的边界情况,比如输入的数是否在合理范围内,但通常PTA的测试用例不会涉及这个问题,只要程序能正确处理常规输入即可。另外,变量的类型是否足够大,如果题目保证输入在int范围内,那么用int类型就可以了。 可能用户会遇到的问题包括:忘记处理整数除法导致平均值错误,或者输出格式与题目要求的不一致。例如,使用整数除法得到平均值,结果会被截断,而不是四舍五入。这时候需要将其中一个操作数转换为浮点型,确保得到浮点数结果。 此外,代码的结构是否清晰,变量命名是否合理,虽然PTA可能不关心这些,但良好的习惯有助于减少错误。例如,变量名a, b, c, d可能不够描述性,但题目中可能只需四个整数,所以也合理。 测试用例方面,比如输入1 2 3 4,总和是10,平均值是2.5,应该输出Sum = 10; Average = 2.5。而输入包含负数的情况,比如-1 2 -3 4,总和是2,平均0.5。这时候程序是否能正确处理负数也需要确认。 总结步骤: 1. 读取四个整数。 2. 计算总和。 3. 计算平均值,注意类型转换。 4. 按格式输出结果。 现在需要将这些步骤转化为C语言代码,并确保语法正确,符合PTA的要求。可能还需要注意代码的简洁性,比如不需要多余的变量,直接计算并输出。</think>要解决PTA上“求整数均值”的C语言编程问题,可按照以下步骤操作: --- ### **问题分析** **题目要求**:输入4个整数,计算它们的**总和**与**平均值**,并按照`Sum = 总和; Average = 平均值`的格式输出,其中平均值保留1位小数。 --- ### **解题思路** 1. **输入处理**:使用`scanf`读取4个整数。 2. **计算总和**:将4个整数相加。 3. **计算平均值**:总和除以4,需转换为浮点数避免整数除法截断。 4. **格式化输出**:按题目要求输出总和和平均值。 --- ### **完整代码** ```c #include <stdio.h> int main() { int a, b, c, d; scanf("%d %d %d %d", &a, &b, &c, &d); // 读取四个整数 int sum = a + b + c + d; // 计算总和 float average = (float)sum / 4; // 转换为浮点数计算平均值 printf("Sum = %d; Average = %.1f", sum, average); // 按格式输出 return 0; } ``` --- ### **代码解释** 1. **输入部分** - 使用`scanf("%d %d %d %d", &a, &b, &c, &d)`读取四个整数,输入时以空格分隔。 2. **计算总和** - 直接相加:`sum = a + b + c + d`。 3. **计算平均值** - 关键点:将总和强制转换为`float`类型,再进行除法运算`(float)sum / 4`,确保结果为浮点数。 - 若直接写`sum / 4`,整数除法会丢弃小数部分(例如:`5/2=2`)。 4. **输出部分** - 使用`printf`按题目格式输出,注意`%.1f`表示保留1位小数。 --- ### **测试示例** **输入**: ``` 1 2 3 4 ``` **输出**: ``` Sum = 10; Average = 2.5 ``` --- ### **常见错误** 1. **未处理整数除法** 错误代码:`average = sum / 4;` 结果:`10/4=2`(错误),正确应转换为浮点数。 2. **输出格式不符** 例如缺少分号`;`或拼写错误(如`Averange`)。 --- ### **总结** - 核心逻辑:总和计算 + 浮点数除法。 - 注意点:强制类型转换`(float)`和输出格式`%.1f`。 - 通过PTA测试的关键:严格按照题目要求的输入输出格式编写代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值