本人一开始是这样写的:
#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;
}
附上两次的耗时情况:
差距蛮明显的。
然后注意下这个while循环里面的条件while (~scanf("%d %d", &l, &r))
,不要写成while (scanf("%d %d", &l, &r))
具体原因如下:
-
scanf
的返回值:-
当 scanf 成功读取两个整数时,返回值是 2(表示成功读取了两个项)。
-
当遇到文件结束符(EOF)或者输入错误时,返回值是 EOF(通常是 -1)。
-
-
使用
~
操作符:-
~
是按位取反运算符。它对整数的每一位进行反转。 -
例如:
-
如果 scanf 返回 2,那么 ~2 的结果是 -3(因为 ~2 反转了二进制的 2,得到 -3)。
-
如果 scanf 返回 -1(即 EOF),那么 ~-1 的结果是 0(因为 ~-1 反转了 -1 的二进制,得到 0)。
-
-
-
循环条件的判断:
在
while (~scanf("%d %d", &l, &r))
中:-
当 scanf 成功读取两个整数(返回 2),条件为 while (~2),即 while (-3),这个条件为真,循环继续。
-
当 scanf 返回 EOF(即 -1),条件为 while (~-1),即 while (0),这个条件为假,循环结束。
-
补充:
在 C 语言中,while
循环的条件判断是基于真值逻辑的:
-
非零值为真:在 C 语言中,任何非零值都被视为真(true),而 0 被视为假(false)。
-
负数也是非零:虽然 -3 是负数,但它仍然是非零,因此在条件判断中被视为真。换句话说,while (-3) 是一个真条件,循环会继续执行。
附上一篇博客cin和scanf的返回值知多少
标签:58,int,scanf,cin,while,区间,EOF,cout From: https://www.cnblogs.com/hisun9/p/18516307