基于cumulative sum query的以下问题,我创建了解决方案。但是在线性复杂度为O(N)的C中解决问题的还有其他方法吗?
问题描述:
William Macfarlane想看一个阵列。
您将获得N个数字和Q个查询的列表。每个查询都是 由两个数字i和j指定;每个查询的答案都是总和 范围[i,j](包括)之间的每个数字。
注意:使用基于0的索引指定查询范围。
输入
第一行包含N,即列表中的整数数(N <= 100,000)。下一行包含保证适合的N个数字 在整数内。列表后面是数字Q(Q <= 10,000)。该 下一个Q行每个包含两个数字i和j,用于指定查询 你必须回答(0&lt; = i,j&lt; = N-1)。输出
输出
对于每个查询,在其自己的行中输出该查询的答案 订购查询。
以下是解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct node {
int first;
int last;
};
int sum_array(int *array, int first, int last) {
int sum = 0;
for (int i = first; i <= last; i++) {
sum += array[i];
}
return sum;
}
int main() {
FILE* input = fopen("share.in","r");
int N = 0;
fscanf(input,"%d",&N);
int *array = (int*)malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
fscanf(input,"%d",&array[i]);
}
int Q = 0;
fscanf(input,"%d",&Q);
struct node query[Q];
for (int i=0; i < Q; i++) {
fscanf(input,"%d",&query[i].first);
fscanf(input,"%d",&query[i].last);
}
fclose(input);
int sum = 0;
for ( int i = 0; i < Q ; i++) {
int first = query[i].first;
int last = query[i].last;
sum = sum_array(array,first,last);
printf("Number of queries : %d , sum is %d\n",i ,sum);
}
free(array);
return 0;
}
更新
答案是好的。但出于某种原因我无法使其发挥作用。
所以这里是重写的代码,如果有人能解释我做错了什么,我会很开心!请记住,我们希望范围为 [first,last]
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct node {
int first;
int last;
};
int sum_array(int *array, int first, int last) {
int sum = 0;
for (int i = first; i <= last; i++) {
sum += array[i];
}
return sum;
}
int main() {
FILE* input = fopen("share.in","r");
int N = 0;
fscanf(input,"%d",&N);
int *array = (int*)malloc(N * sizeof(int));
int *integralArray = (int*)malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
fscanf(input,"%d",&array[i]);
integralArray[i] = array[i] + ((i > 0) ? array[i-1] : 0);
}
int Q = 0;
fscanf(input,"%d",&Q);
struct node query[Q];
for (int i=0; i < Q; i++) {
fscanf(input,"%d",&query[i].first);
fscanf(input,"%d",&query[i].last);
}
fclose(input);
int sum = 0;
for (int i = 0; i < Q ; i++) {
int first = query[i].first;
int last = query[i].last;
sum = integralArray[last] - integralArray[first - 1];
printf("Number of queries : %d , sum is %d\n",i ,sum);
}
free(array);
return 0;
}
答案 0 :(得分:2)
你将形成整数数组。修改为:
int *array = (int*)malloc(N * sizeof(int));
int *integralArray = (int*)malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
fscanf(input,"%d",&array[i]);
integralArray[i] = array[i] + ((i > 0) ? integralArray[i-1] : 0);
}
因此integralArray[i]
处的元素是array
中从0
到i
的所有元素的总和。
然后,要获得从a
到b
的总和,其中a > b
,integralArray[b]
是从0
到b
的总和, integralArray[a]
是从0
到a
的总和,因此您只需计算integralArray[b] - integralArray[a]
即可获得a
到b
的总和。直观地,integralArray[b]
包含您想要的数字,但也包括a
之前的数字。你不想要那些,所以你再把它们拿掉。
适当地包含或排除a
处的号码和b
处的号码。给定的数字将包括b
处的数字,但不包括a
处的数字。您可以将integralArray
调整为更早(integralArray[b]
是从0到b-1
的总和)或调整您的指数。