58. 区间和

题目

本人一开始是这样写的:

#include <iostream>

using namespace std;

const int N = 100010;
int n;
int s[N];

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        cin >> x;
        s[i] = s[i - 1] + x;
    }
    
    int l = 0, r = 0;
    while (cin >> l && cin >> r)
    {
        cout << s[r + 1] - s[l + 1] << endl;
    }
    return 0;
    
}

发现结果不对。

仔细再看了一遍代码,发现是 cout << s[r + 1] - s[l + 1] << endl;这一句的问题,应该改成cout << s[r + 1] - s[l] << endl;,即l + 1那个位置的数也是在区间[l + 1 , r + 1]里的,也要加上。

改成这样就对了:

#include <iostream>

using namespace std;

const int N = 100010;
int n;
int s[N];

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        cin >> x;
        s[i] = s[i - 1] + x;
    }
    
    int l = 0, r = 0;
    while (cin >> l && cin >> r)
    {
        cout << s[r + 1] - s[l] << endl;
    }
    return 0;
    
}

再补充一个点(在卡哥写的题解上看到的):

C++ 代码 面对大量数据 读取 输出操作,最好用scanf 和 printf,耗时会小很多

于是将代码改成这样:

#include <iostream>

using namespace std;

const int N = 100010;
int n;
int s[N];

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        scanf("%d", &x);
        s[i] = s[i - 1] + x;
    }
    
    int l = 0, r = 0;
    while (~scanf("%d %d", &l, &r))
    {
        printf("%d\n", s[r + 1] - s[l]);
    }
    return 0;
    
}

附上两次的耗时情况:

img

差距蛮明显的。

然后注意下这个while循环里面的条件while (~scanf("%d %d", &l, &r)),不要写成while (scanf("%d %d", &l, &r))

具体原因如下:

  1. scanf的返回值:

    • 当 scanf 成功读取两个整数时,返回值是 2(表示成功读取了两个项)。

    • 当遇到文件结束符(EOF)或者输入错误时,返回值是 EOF(通常是 -1)。

  2. 使用 ~ 操作符:

    • ~ 是按位取反运算符。它对整数的每一位进行反转。

    • 例如:

      • 如果 scanf 返回 2,那么 ~2 的结果是 -3(因为 ~2 反转了二进制的 2,得到 -3)。

      • 如果 scanf 返回 -1(即 EOF),那么 ~-1 的结果是 0(因为 ~-1 反转了 -1 的二进制,得到 0)。

  3. 循环条件的判断:

    while (~scanf("%d %d", &l, &r)) 中:

    • 当 scanf 成功读取两个整数(返回 2),条件为 while (~2),即 while (-3),这个条件为真,循环继续。

    • 当 scanf 返回 EOF(即 -1),条件为 while (~-1),即 while (0),这个条件为假,循环结束。

使用 ~操作符的目的是将 scanf 的返回值转换成一个可以用于循环判断的形式,确保在成功读取数据时循环继续,而在遇到结束或错误时退出。

补充:

在 C 语言中,while 循环的条件判断是基于真值逻辑的:

  • 非零值为真:在 C 语言中,任何非零值都被视为真(true),而 0 被视为假(false)。

  • 负数也是非零:虽然 -3 是负数,但它仍然是非零,因此在条件判断中被视为真。换句话说,while (-3) 是一个真条件,循环会继续执行。

附上一篇博客cin和scanf的返回值知多少

posted @ 2024-10-30 18:00  hisun9  阅读(14)  评论(0编辑  收藏  举报