难以接受的是这本应该在大一大二就逐渐经历的coding & debugging经历我居然到大三下才接触到。真是羞耻
第一想法确实是遇到一个区间就在数组中累加。很通人性的想法。
#include <stdio.h>
#include <stdlib.h>
int IntervalSum(int* arr, int left, int right);
int main(){
int arraysize;
scanf("%d", &arraysize);
// printf("arraysize = %d\n", arraysize);
int* arr = (int*)malloc(sizeof(int) * arraysize);
for(int i = 0; i < arraysize; i++){
scanf("%d", &arr[i]);
// printf("ith arr_element = %d ", arr[i]);
}
int left, right;
while(scanf("%d %d", &left, &right) == 2){
int ans = IntervalSum(arr, left, right);
printf("%d\n", ans);
}
return 0;
}
int IntervalSum(int* arr, int left, int right){
int int_sum = 0;
for(int k = left; k <= right; k++){
int_sum += arr[k];
}
return int_sum;
}
/**************************************************************
Problem: 1070
User: odCYZ6rIpK_ZEEth56_tjfAkOnvg [kamaCoder567695]
Language: C
Result: 正确
Time:793 ms
Memory:1584 kb
****************************************************************/
后来我参考了前缀和的想法,新建了一个数组空间存储上前缀和进而计算出结果。
#include <stdio.h>
#include <stdlib.h>
int IntervalSum(int *arr, int left, int right, int size);
int main() {
int arraysize;
scanf("%d", &arraysize);
// printf("arraysize = %d\n", arraysize);
int *arr = (int *)malloc(sizeof(int) * arraysize);
for (int i = 0; i < arraysize; i++) {
scanf("%d", &arr[i]);
// printf("ith arr_element = %d ", arr[i]);
}
int left, right;
while (scanf("%d %d", &left, &right) == 2) {
int ans = IntervalSum(arr, left, right, arraysize);
printf("%d\n", ans);
}
return 0;
}
int IntervalSum(int *arr, int left, int right, int size) {
int* prefix_sum = (int*)malloc(sizeof(int) * size);
int prefix = 0;
for (int j = 0; j < size; j++){
prefix_sum[j] = prefix;
prefix += arr[j];
}
prefix_sum[size] = prefix;
int ans = prefix_sum[right+1] - prefix_sum[left];
return ans;
}
/**************************************************************
Problem: 1070
User: odCYZ6rIpK_ZEEth56_tjfAkOnvg [kamaCoder567695]
Language: C
Result: 内存超限
****************************************************************/
想必是新建数组带来了不必要的内存占用,相当于导致了原来的两倍了。
改变策略,我想要实现在原数组上直接修改。但是这个修改操作本身会遇到些许问题,比如:修改应该是从后往前的,否则会导致前后不一致;从后往前需要提前知道整个数组的总和,但是如何得来?为了不增加时间复杂度,也是想到在 scanf 的时候就将数组的总和计算出来。
虽然这样说出来我自己都感觉得到这些操作其实很低端,但是这样的经历到大三我才开始遭遇。
Once again, shame on me.
最后debug一番得到了时间和空间复杂度在我认知范围内最好的算法。
#include <stdio.h>
#include <stdlib.h>
int main() {
// input operation
int arraysize;
int sum_all = 0;
scanf("%d", &arraysize);
int *arr = (int *)malloc(sizeof(int) * arraysize);
for (int i = 0; i < arraysize; i++) {
scanf("%d", &arr[i]);
sum_all += arr[i];
}
// re-build a prefix_sum_array **right at the original array's address**
int left, right;
int prefix = 0;
for (int k = arraysize - 1; k >= 0; k--) {
int temp = arr[k];
arr[k] = sum_all;
sum_all -= temp;
}
// compute the ans
while (scanf("%d %d", &left, &right) == 2) {
int ans;
if(left != 0){
ans = arr[right]- arr[left-1];
}
else{
ans = arr[right];
}
printf("%d\n", ans);
}
return 0;
}
同样的前缀和思路,也是成功地自己实现出了进阶版本的区间和——44.开发商购买土地
#include <stdio.h>
#include <stdlib.h>
int main(){
// input operation
int col, row;
scanf("%d %d", &row, &col);
int* row_sum = (int*)malloc(sizeof(int) * row);
int* col_sum = (int*)malloc(sizeof(int) * col);
int all_sum = 0;
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
int temp;
scanf("%d", &temp);
row_sum[i] += temp;
col_sum[j] += temp;
all_sum += temp;
}
}
// for(int i = 0; i < row; i++){
// printf("%d ", row_sum[i]);
// }
// printf("\n");
// for(int j = 0; j < col; j++){
// printf("%d ", col_sum[j]);
// }
// printf("\n");
// re-build prefix-sum arrays
int all_sum_row = all_sum;
int all_sum_col = all_sum;
for(int k = row-1; k >= 0; k--){
int temp_k = row_sum[k];
row_sum[k] = all_sum_row;
all_sum_row -= temp_k;
}
for(int m = col-1; m >= 0; m--){
int temp_m = col_sum[m];
col_sum[m] = all_sum_col;
all_sum_col -= temp_m;
}
// for(int i = 0; i < row; i++){
// printf("%d ", row_sum[i]);
// }
// printf("\n");
// for(int j = 0; j < col; j++){
// printf("%d ", col_sum[j]);
// }
// printf("\n");
// discuss the row-wise situation
int res_row = all_sum;
for(int wall_row = 0; wall_row < row-1; wall_row++){
int temp_row = row_sum[row-1] > 2*row_sum[wall_row] ? row_sum[row-1] - 2*row_sum[wall_row] : 2*row_sum[wall_row] - row_sum[row-1];
res_row = res_row < temp_row ? res_row : temp_row;
}
// discuss the rol-wise situation
int res_col = all_sum;
for(int wall_col = 0; wall_col < col-1; wall_col++){
int temp_col = col_sum[col-1] > 2*col_sum[wall_col] ? col_sum[col-1] - 2*col_sum[wall_col] : 2*col_sum[wall_col] - col_sum[col-1];
res_col = res_col < temp_col ? res_col : temp_col;
}
int res = res_col < res_row ? res_col : res_row;
printf("%d", res);
return 0;
}