> 文档中心 > CSP 202112-1 序列查询(详解)

CSP 202112-1 序列查询(详解)


题目分析:

1、有一个数组A,里面有 n+1 个数,范围是 [0,N),注意,左闭右开,这个数组的特点是:
(1)第 0 位一定是 0,记 A[0] = 0
(2)数组 A 里的数越来越大
(3)最大的时候不能等于 N
(4)一共有 n+1 位
2、另有一个序号数组 ,里面是自然数:0、1、2、3、4、5、、、、N-1。一共有 N 位
3、我们再规定一个数组 B(i),对应题目中的 f(i), 其特点是这样的:
(1)它的第 i 位的值等于 不超过序号数组第 i 位的值 的数组A里的最大位号
(2)换言之,B(i) 里存的是数组 A 的某些满足条件的位号
(3)而这个所谓的条件就是:不超过序号数组第 i 位的值 的数组A里的最大位号
(4)一共有 N 位

例如:
A = { 0258}
序号数组 = { 0,1,2,3,4, 5, 6, 7,8,9}

那么由数组 B 的定义可知:
B 中第一位:数组 A 里的值不超过 0 的最大值的位号,即 0 的位号 0
B 中第二位:数组 A 里的值不超过 1 的最大值的位号,依然是 0 的位号 0
B 中第三位:数组 A 里的值不超过 2 的最大值的位号,即 2 的位号 1
B 中第四位:数组 A 里的值不超过 3 的最大值的位号,即 2 的位号 1
、、、、、

所以:
B = { 0,0,1,1,1,2,2,2,3,3}

4、知道 数组 B 后求出 B 的所有元素之和 sum

解题思路:

1、我们可以发现,只要求出 数组 B ,一切都好说了,求 sum 岂不是有手就行
2、数组 B 的位数与 序号数组 的位数相同,只是值不同
3、数组 B 的每一位的值也与 序号数组 有关
4、B 的每一位的值要么不变,要么加 1

{ 0,1,2,3,4,5, 6, 7,8,9}
{ 0, 0, 1, 1, 1, 2, 2, 2, 3, 3}

5、很明显,变得时候(即需要加 1 的时候)都是 序号数组 的值等于数组 A 的值的时候
6、自然的,我们可以把需要变的位置记录先用数组下来,记为 1,其余位置记为 0
7、与其说是 序号数组 的值等于数组 A 的值,不如说就是 序号数组的位数 等于 、数组 A 的值
8、因为第 0 位固定是 0 ,所以从第 1 位开始记录:

B[0] = 0
B[2] = 1
B[5] = 1
B[8] = 1
即 B = {0,0,1,0,0,1,0,0,1,0 }

9、现在我们把需要加 1 的位置记录下来了,现在B的值从0开始,需要加的时候,直接加就好了:

第 0 位肯定为0,所以从第 1 位开始:

for(i=1; i<N; i++) //B[0] = 0;{B[i] = B[i] + B[i-1];}

最后得出真正的数组 B:B = { 0,0,1,1,1,2,2,2,3,3 }

代码实现:

#include int main(){//n,代表下一行输入n个数,N代表共有N个序号,注意从0开始int n, N;scanf("%d %d", &n ,&N);int B[N] = {0};int i, j;int sum = 0;//注意A[0]固定为0,所以从A[1]开始存,到A[n]结束: for(i=1; i<=n; i++)  {scanf("%d", &j); B[j]++;  //标记出要变的位置,暂时用 B 记录}for(i=1; i<N; i++) //B[0] = 0;{B[i] = B[i] + B[i-1]; //求出真正的数组 Bsum = sum + B[i];  //求和}printf("%d",sum);return 0; } 

另解:

CSP 202112-1 序列查询(详解)
我们直接从数组 A 数组 B 出发,找出规律,发现有 2-0 个 0,5-2 个 1,8-5 个 2,10-8 个 3,即:

A[1] - A[0]个 0
A[2] - A[1]个 1
A[3] - A[2]个 2
再加上,
N - A[3]个 3

#include int main(){//n,代表下一行输入n个数,N代表共有N个序号,注意从0开始int n, N;scanf("%d %d", &n ,&N);int A[N] = {0};int i;int sum = 0;//注意A[0]固定为0,所以从A[1]开始存,到A[n]结束: for(i=1; i<=n; i++)  {scanf("%d", &A[i]); }for(i=1; i<n; i++){sum = sum + i*( A[i+1] - A[i] );}sum = sum + n*(N-A[n]);printf("%d",sum);return 0; }