题目:gg查成绩
题目描述
这一天gg拿到了一份,超多的考试数据a 。 老师要求他按照询问数据告诉老师,第几个到第几个同学的分数和是多少 ?
gg最近入职字节跳动了,没有时间处理这种极其简单的问题,所以请你顺手秒一下。
输入描述
bash 第一行n m ( n个同学 m次询问)
1 <= n <= 106
1 <= m <= 104
第二行输入n个整数表示成绩
a1 a2…an (0 <= ai<= 100) 1<=i<=n
以下m行为两个整数 bi bj 表示第几个到第几个同学(从1开始)
1<=bi<=bj<=n
输出描述
m行查询结果
示例1
输入
10 3
11 22 33 44 55 66 77 88 99 10
1 4
2 10
5 7
输出
110
494
198
说明:
注意第几个是按照输入顺序 不要排序 不要排序 不要排序
思路
一、 如果按照常规方法解决的话:
- 开设一个1000000的int数组
- 输入n,m
- 输入n个数存入数组
- 输出m组bi bj
- 用循环实现加法
但是这样的时间复杂度就可能会非常大(1000000不是一个很小的数字,最大为O(n*(m+1))
二、 如果用另一种方法:
- 开设一个1000000的int数组(用来存放前 i 项和)
- 输入n,m
- 输入n 个数,并加上数组中前一项存入数组
- 输入 m 组bi bj
- 求和直接用
第 bj 项 - 第(bi-1)项
这样的时间复杂度就会大约为O(n);
总结
在做题时,尽可能将时间复杂度降低
以下为代码:
(一)
//未能通过(通过71.43% 运行超时)
#include<stdio.h>
int c[1000001]; //在我的编译器上main函数里不能直接开这么大的数组,但是作为全局变量就可以
int main()
{
int n,m;
scanf("%d %d",&n,&m);
//int c[1000001];
int i;
for(i=1;i<=n;i++)
{
scanf("%d",&c[i]);
}
while(m)
{
int bi,bj;
int s=0;
scanf("%d %d",&bi,&bj);
for(;bi<=bj;bi++)
{
s+=c[bi];
}
printf("%d\n",s);
s=0;
m--;
}
}
(二)
#include<stdio.h>
int c[1000001];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
//int c[1000001];
int i;
c[0]=0;
for(i=1;i<=n;i++)
{
scanf("%d",&c[i]);
c[i]+=c[i-1];
}
while(m)
{
int bi,bj;
scanf("%d %d",&bi,&bj);
printf("%d\n",c[bj]-c[bi-1]);
m--;
}
}
题目来源:https://ac.nowcoder.com/acm/contest/11471/C
本文探讨了一种优化算法,用于快速解决在大量考试数据中查找指定范围内学生分数之和的问题。通过建立前缀和数组,将时间复杂度从O(n*m)降低到O(n),显著提高了效率。代码示例展示了两种方法,一种常规方法可能导致运行超时,而优化后的代码则能有效避免此类问题。
826

被折叠的 条评论
为什么被折叠?



