给出一个长度为n 的整数数组a,下标从1开始,q次询问,每次询问给出两个区间每次询问给出两个区间[11,r1],[l2,r2],
先让下标在[11,r1]里的元素乘以2,再让下标在[l2,r2]里的元素乘以 2,输出每次询问操作后数组总和是多少?
询问是相互独立的,每次询问后都把数组还原为初始状态。
第一行包含两个整数n、q(1<=n,q<=2x1e5),表示数组大小和询问个数。
第二行包含n个整数ai(-1e5<= ai <= 1e5),表示数组a,接下来q行,每行四个整数11,r1,l2,r2(1<l1<=r1<=n,1<l2<=r2<=n),表示操作区间.
输出描述:
输出包含q行,每行一个整数,表示每次询问操作后的数组总和。
示例:
输入:
3 2
1 2 1
1 2 2 3
1 1 2 2
输出:
12
7
2024年9月,讯飞笔试题,应该算一道简单题。
解题思路:copy初始数组用于每次单独的询问,常规的数组操作与求和。
需要考虑的点:1)保存初始数组;2)下标从1开始;
我的代码中存在的问题:1)最开始calloc的参数部分,size给了0,导致free出错,非常傻X的错误。2)实在太简单,找不出其它需要说明的点;
用时:38min左右(敲+调试);
#include<stdio.h>
#include<stdlib.h>int sum(int* a, int n)
{int sum = 0;if (NULL == a || n < 1){return sum;}for (int j = 0; j < n; j++){sum += a[j];}return sum;
}void print_output(int* a, int n)
{if (NULL == a || n < 1){return;}for (int j = 0; j < n; j++){printf("%d\n", a[j]);}
}bool copy_int_array(int* src, int n, int* des)
{//int ret = -1;if (NULL == src || n < 1 || NULL == des){return 0;}for (int j = 0; j < n; j++){des[j] = src[j];}return 1;
}void query()
{int aLen, iQueryCnt;scanf_s("%d %d", &aLen, & iQueryCnt);if (aLen < 1 || iQueryCnt < 1){printf("输入不正确,输入的数组大小为%d,询问次数为%d\n", aLen, iQueryCnt);return;}int* a = (int*)calloc(aLen, sizeof(int));int* aCopy = (int*)calloc(aLen, sizeof(int));int* retQuery = (int*)calloc(iQueryCnt, sizeof(int));//接收数组a的输入,并copy一份a作为原始状态for (int i = 0; i < aLen; i++){scanf_s("%d", &a[i]);aCopy[i] = a[i];}int l1, r1, l2, r2, iCnt = 0;while (iQueryCnt-- > 0){ scanf_s("%d %d %d %d", &l1, &r1, &l2, &r2);l1--, r1--, l2--, r2--;for (int j = l1; j <= r1; j++){aCopy[j] *= 2;}for (int k = l2; k <= r2; k++){aCopy[k] *= 2;}retQuery[iCnt++] = sum(aCopy, aLen);//iCnt++;//printf("%d\n", sum_of_array);int ret = copy_int_array(a, aLen, aCopy);if (!ret){printf("返回数组初始状态失败!\n");return;}} print_output(retQuery, iCnt);free(a);free(aCopy);free(retQuery);
}int main()
{query();return 0;
}