1104. Sum of Number Segments (20)【数学题】——PAT (Advanced Level) Practise

本文介绍了一种快速计算给定正数数列所有连续子序列(段)元素之和的方法,并提供了一个C++实现示例。对于输入的数列,算法能够高效地计算出所有可能子序列的总和。

题目信息

1104. Sum of Number Segments (20)

时间限制200 ms
内存限制65536 kB
代码长度限制16000 B
Given a sequence of positive numbers, a segment is defined to be a consecutive subsequence. For example, given the sequence {0.1, 0.2, 0.3, 0.4}, we have 10 segments: (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1, 0.2, 0.3, 0.4) (0.2) (0.2, 0.3) (0.2, 0.3, 0.4) (0.3) (0.3, 0.4) (0.4).

Now given a sequence, you are supposed to find the sum of all the numbers in all the segments. For the previous example, the sum of all the 10 segments is 0.1 + 0.3 + 0.6 + 1.0 + 0.2 + 0.5 + 0.9 + 0.3 + 0.7 + 0.4 = 5.0.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N, the size of the sequence which is no more than 10^5. The next line contains N positive numbers in the sequence, each no more than 1.0, separated by a space.

Output Specification:

For each test case, print in one line the sum of all the numbers in all the segments, accurate up to 2 decimal places.

Sample Input:
4
0.1 0.2 0.3 0.4
Sample Output:
5.00

解题思路

直接看代码吧,,不想多说,

AC代码

#include <cstdio>

int main()
{
    int n;
    long long st = 0;
    double s = 0, v;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i){
        scanf("%lf", &v);
        st += n - i - i;
        s += v * st;
    }
    printf("%.2f\n", s);
    return 0;
}
### 错误分析与修复方法 用户提供的测试用例为 `166.111.4.123.`,该输入被错误地判断为合法(输出为 `Y`),但实际上应为非法(输出为 `N`)。此问题的根本原因在于代码未能正确处理末尾多余的`.`符号[^1]。 #### 错误原因 在解析字符串时,如果使用了基于`.`的分割逻辑,但未对最后一个数段是否为空进行验证,则可能导致错误。例如,对于输入`166.111.4.123.`,分割后会得到四个部分:`166`、`111`、`4` 和一个空字符串``。由于空字符串不满足IPv4数段的规则(数段必须由1到3位数字组成),因此整个地址应被判为非法。 此外,代码可能未严格检查分割后的数段数量是否恰好为4。如果分割后数段数量不足或超过4,则也应判定为非法。 #### 修复方法 为了修复上述问题,需确保以下几点: 1. 在分割字符串后,验证分割结果是否恰好包含4个数段[^1]。 2. 验证每个数段是否为空,并确保其长度在1到3之间[^1]。 3. 检查每个数段的数值范围是否在0到255之间,并排除前导零的情况。 以下是修复后的代码实现: ```cpp #include <iostream> #include <string> #include <vector> #include <sstream> using namespace std; bool isValidIPv4Segment(const string& segment) { if (segment.empty() || segment.size() > 3) return false; // 检查数段长度是否合法 for (char c : segment) { if (!isdigit(c)) return false; // 检查是否全为数字 } int value = stoi(segment); if (value < 0 || value > 255) return false; // 检查数值范围 if (segment.size() > 1 && segment[0] == '0') return false; // 检查前导零 return true; } bool isValidIPv4(const string& ip) { vector<string> segments; stringstream ss(ip); string segment; while (getline(ss, segment, '.')) { segments.push_back(segment); // 分割字符串 } if (segments.size() != 4) return false; // 确保恰好有4个数段 for (const string& seg : segments) { if (!isValidIPv4Segment(seg)) return false; // 验证每个数段 } return true; } int main() { string ip; cout << "请输入一个IP地址: "; cin >> ip; if (isValidIPv4(ip)) { cout << "Y" << endl; } else { cout << "N" << endl; } return 0; } ``` #### 测试用例 - 输入:`166.111.4.123.` 输出:`N` 原因:末尾存在多余的`.`,导致分割后最后一个数段为空[^1]。 - 输入:`192.168.1.1` 输出:`Y` 原因:符合IPv4格式的所有规则。 - 输入:`256.100.50.25` 输出:`N` 原因:第一个数段值超出范围。 - 输入:`192.168.01.1` 输出:`N` 原因:第三个数段存在前导零。 - 输入:`192.168.1` 输出:`N` 原因:分割后数段数量不足4。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值