CCF 202112-1 序列查询 python 满分

56 篇文章 4 订阅

题目叙述

问题描述:略

输入格式:略

输出格式:略

样例

样例1输入
3 10
2 5 8
样例1输出
15

样例2输入
9 10
1 2 3 4 5 6 7 8 9
样例2输出
45

满分证明

同样逻辑代码,Python 只有50分,C++有100分
在这里插入图片描述

根据提示对Python代码进行优化后拿到满分。
在这里插入图片描述

解题思路

第一题就要求优化,还是第一次碰到。
第一次做此题,想到了调用python自带的包——bisect,不过后面实际通过测试并没有用此包。
因为自己做题量太少,并未及时准确找到解题思路。通过观看参考博文1视频才对此题一知半解。这里考察的是对数据的敏感程度和对索引0的处理。

第一次,解题思路用了暴力解法,双重For循环;
一般第一题都是一层for循环解决问题,所以需要优化;

第二次,我把里面for循环优化为While循环,但还是超时;

第三次,直接代入参考博文1的C++代码,实验后可以得到满分;
这里的解题思路是:

  1. 以N为遍历数组,控制索引变动;
  2. fx的值根据当前x与索引以及输入数组关系计算;
  3. 初始化索引为1,在输入数组前插入0方便计算;
  4. 依次遍历从1到N-1的索引——range(1, N)
    4.1 如果x小于输入数组当前索引值: fx等于当前索引减1
    4.2 如果x等于输入数组当前索引值:fx等于当前索引
    4.2.1 如果输入数组当前索引值小于n:当前索引加1
    4.3 如果x大于输入数组当前索引值:fx等于当前索引

具体看代码可能更清晰。

第四次,我把C++的解题思路迁移到Python上,奇怪的是并不能得满分而是显示超时==(这可能就是之前CCF官方说的Python虽然比C/C++用着方便,但运行速度不如他们。)==

第五次,利用题目中提示给出的样例:
分析给出fx以及输入数组关系,分析出下面表达式(可能这就是刷题多了一眼便能看出来吧):

sum[A]=sum[A]+(A[i]-A[i-1])*(i-1)
如果A[-1]小于N,则后面的需要单独计算。
具体推导可查看参考博文2参考博文3参考博文4

第六次参考博文2提到的差分+前缀和,用C++也可以得满分。

第七次,我将参考博文2提到的差分+前缀和改写为用Python形式提交,系统则显示超时,但不知道要怎么优化;如果有大佬懂,烦请在下面留个言,Thanks♪(・ω・)ノ。

01 暴力求解Python 超时50分代码

n, m = map(int, input().split())
ori_li = list(map(int, input().split()))
ori_li.insert(0, 0)
sum_f = 0

max_ori_li = max(ori_li)
tem_i = 0

for i in range(max_ori_li + 1):
    for j in range(len(ori_li)):
        tem_i = j
        if i < max(ori_li[:j + 1]):
            tem_i = tem_i - 1
            break
    sum_f = sum_f + tem_i

if max_ori_li < m:
    for _ in range(m - 1 - max_ori_li):
        sum_f = sum_f + len(ori_li) - 1

print(sum_f)

02 初步优化Python 超时50分代码

n, m = map(int, input().split())
ori_li = list(map(int, input().split()))
ori_li.insert(0, 0)

sum_f = 0
last_i = 0
max_ori_li = max(ori_li)
tem_i = 0
pre_li = []
for i in range(max_ori_li + 1):
    while ori_li[last_i] <= i:
        if last_i + 1 < len(ori_li):
            last_i = last_i + 1
        else:
            last_i = last_i + 1
            break
    tem_i = last_i - 1
    sum_f = sum_f + tem_i

if max_ori_li < m:
    sum_f = sum_f + (len(ori_li) - 1) * (m - max_ori_li - 1)


print(sum_f)

03 满分C++代码

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main(){
	int n, N;
	int A[210];
	cin >> n >> N;
	A[0] = 0;
	for (int i = 1; i <= n; i++) {
		cin >> A[i];
	}
	int i = 1;
	int fx = 0;
	int sum = 0;
	for (int x = 1; x < N; x++) {
		if (x < A[i]){
			fx = i - 1;
		}
		else if (x == A[i]) {
			fx = i;
			if (i < n) {
				i++;
			}
		}
		else if (x > A[i]) {
			fx = i;
		}
		sum = sum + fx;
	}
	cout << sum;
	return 0;
}

04 同样逻辑下Python50分代码

n,m=map(int,input().split())
ori_li=list(map(int,input().split()))
ori_li.insert(0,0)
sum_f=0
index=1
fx=0
for x in range(1,m):
    if x < ori_li[index]:
        fx=index-1
    elif x == ori_li[index]:
        fx=index
        if index<n:
            index+=1
    elif  x > ori_li[index]:
        fx=index
    sum_f+=fx
print(sum_f)


05 优化后满分Python代码

n,m=map(int,input().split())
ori_li=list(map(int,input().split()))

ori_li.insert(0,0)

sum_f=0
index=1
fx=0
for x in range(1,n+1):
    sum_f+=(ori_li[x]-ori_li[x-1])*(x-1)

if m>ori_li[-1]:
    sum_f+=n*(m-ori_li[-1])
print(sum_f)

06 差分+前缀和满分C++代码

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int M = 1e7 + 5;
int n, N, dif[M], f[M];
int main() {
	int a;
	cin >> n >> N;
	for (int i = 1; i <= n; i++) {
		cin >> a;
		dif[a]++;
		//差分数组,无论操作多少次,最后f(x)求和的时候都只计算一次
	}
	int res = 0;
	for (int i = 1; i < N; i++) {
		//求得f(i)的方法
		f[i] = f[i - 1] + dif[i];
		//将此f(i)加入和
		res += f[i];
	}
	cout << res;
	return 0;
}

07 差分+前缀和Python超时代码

n, N = map(int, input().split())
ori_li = list(map(int, input().split()))

f = [0 for _ in range(int(1e7+5))]
dif = [0 for _ in range(int(1e7+5))]
for i in ori_li:
    dif[i] = dif[i] + 1

sum_f = 0
index = 1
fx = 0
for i in range(1, N):
    f[i] = f[i - 1] + dif[i]
    sum_f += f[i]

print(sum_f)

感谢及参考博文

部分内容参考以下链接,这里表示感谢 Thanks♪(・ω・)ノ
参考博文1 202112(第24次)CSP真题202112-1,2讲解
https://www.bilibili.com/video/BV1v34y117Vi
参考博文2 CCF CSP 202112-1题(两种方法AC)
https://blog.csdn.net/Tgmmmmmmmm/article/details/123436013
参考博文3 【CCF-CSP】202112-1-序列查询100分
https://blog.csdn.net/qq_21471309/article/details/122635634
参考博文4 【CCF-CSP】202112-1-序列查询100分
https://blog.csdn.net/weixin_45238806/article/details/123053151

需者自取传送门(∩ᄑ_ᄑ)⊃━☆【CCF 2013-2021】本博主整理历年至少前两题 python 满分代码目录

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值