洛谷 CSP-J 2021 分糖果+插入排序 个人解答的优化过程以及详解

news2024/9/24 9:23:24

首先声明这两道题目第一题很简单,读者可以不看解答自己先做一遍题目,看看能不能获得满分,我就是因为无意识考虑时间复杂度的问题没有获得满分最开始,然后我进行了优化,获得了满分,但是第二题的难度较大,读者可以仔细领会,接下来请看题目:

首先我们来看第一道题分糖果:

样例以及数据范围:

 我一开始的思路很简单,那就是从L到R进行枚举,不断更新ans得到最后的答案:

#include<iostream>
using namespace std;
int n,L,R;
int ans=-1;
int main(){
	cin>>n>>L>>R;
	for(int i=L;i<=R;i++){
		ans=max(ans,i%n);
	}
	cout<<ans<<endl;
	return 0;
}

这段代码得不到满分,在极端的情况下会导致超时,不过如果不追求满分的同学的话可以使用,因为这段代码已经有九十分了,然后接下来我进行了优化,我来讲一下我的优化思路:因为很明显我们最后的答案就是1到n-1,所以我们可以考虑引入变量,然后计算出L和R模去n的值以及除去n的值,如果除去n的两个变量相减大于等于1就说明L和R的差必定大于等于n也就意味着存在一个值x属于L到R,让我分到n-1个苹果,亦或者L,R其中一个值模去n得到n-1的话,同样可以判断出能获得n-1个苹果,否则的话我们将模出来的两个变量从小到大进行枚举最后不断更新就可以得到我们想要的答案:

#include<iostream>
using namespace std;
int n,L,R;
int ans=-1;
int main(){
	cin>>n>>L>>R;
	if(R-L>=n-1){
		cout<<n-1<<endl;
		return 0;
	}
	int t1=L%n,t2=L/n,t3=R%n,t4=R/n;
	if(t1==n-1 || t3==n-1 || t4-t2>=1){
		cout<<n-1<<endl;
		return 0;
	}  
	for(int i=min(t1,t3);i<=max(t1,t3);i++){
	    ans=max(ans,i);
	    }
	    cout<<ans<<endl;
	    return 0;
}

好了,接下来是第二题,插入排序:

来看贼长的题干:

样例以及数据范围:

 

 好了接下来来分析一下这一道题目:
这道题目我一开始的想法也就是模拟,首先把该输入的输入了,只不过我们需要引入一个变量数组t,因为如果是操作二的话我们每次都会对数组进行排序但是进行的操作并不会保留,因此我们可以利用这个t变量数组先存下一开始的a数组当操作结束之后再把a数组利用t数组还原:

#include<iostream>
using namespace std;
int n,q;
const int N=10000;
int a[N],t[N];
int main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=q;i++){
		int p;
		cin>>p;
		if(p==1){
			int x,v;
			cin>>x>>v;
			a[x]=v;
		}
		else {
			int x;
			cin>>x;
			int m=x;
			for(int j=1;j<=n;j++)
			t[j]=a[j];
			for(int i=2;i<=n;i++){
				for(int j=i;j>=1;j--){
					if(a[j]<a[j-1]){
						if(j==m){
							int temp=a[j];
							a[j]=a[j-1];
							a[j-1]=temp;
							m=j-1;
						}
						else if(j-1==m){
							int temp=a[j];
							a[j]=a[j-1];
							a[j-1]=temp;
							m=j;
						}
						else {
							int temp=a[j];
							a[j]=a[j-1];
							a[j-1]=temp;
						}
					}
				}
			}
			cout<<m<<endl;
			for(int k=1;k<=n;k++)
			a[k]=t[k];
		}
	}
	return 0;
}

but,出题人当然不会这么好心让我用模拟的思路就能直接过掉所有测试点,完完全全的超时了:

最后的结果就是只有五十多分,离满分具有相当大的差距 。

那么接下来就是想一下如何写一个可以获得满分的代码了,当然是运用我们的老伙伴:结构体了,先放代码吧,代码下面我会进行讲解:

#include<bits/stdc++.h>
using namespace std;
int ans[8100];
int n,Q;
struct number{
	int val,pos;
	bool operator < (const number &A){
		return (val<A.val) || (val==A.val && pos<A.pos);
	}
}a[8100];
int main(){
       cin>>n>>Q;
       for(int i=1;i<=n;i++){
	       cin>>a[i].val;
	       a[i].pos=i;
	   }
	   for(int i=1;i<=n;i++)
	   {
	   	for(int j=i+1;j<=n;j++)
	   	   if(a[j]<a[i])
	   	   swap(a[j],a[i]);
	   }
	   for(int i=1;i<=n;i++){
	   	ans[a[i].pos]=i;
	   }
	   for(int i=1;i<=Q;i++){
	   	int op;
	   	cin>>op;
	   	if(op==2){
	   		int x;
	   		cin>>x;
	   		cout<<ans[x]<<endl;
		   }
		   else {
		   	int x,v;
		   	cin>>x>>v;
		   	int p=ans[x];
		   	a[p].val=v;
		   	number tmp=a[p];
		   	for(int j=p;j<n;j++){
		   		a[j]=a[j+1];
			   }
			   a[n]=tmp;
			   for(int j=n;j>=2;j--){
			   	if(a[j]<a[j-1]) swap(a[j],a[j-1]);
			    else break;
			   }
			   for(int j=1;j<=n;j++)
			   ans[a[j].pos]=j;
		   }
     }
     return 0;
}

接下来我对这一段代码进行解释:

这段代码定义了一个结构体以及ans数组,结构体里面有两个变量val和pos,分别代表了数字大小以及排名,结构体里面重载了运算符,排序规则就是如果分数不一样就按照从小到大的顺序进行排序,否则就是一开始的序号pos小的排前面,然后把所有需要输入的都输入了之后,将结构体按排序规则进行排序,这里使用的是冒泡排序法,ans数组用于存储原结构体中val的大小顺序,在排序结束后,将它们一开始的排名存储到ans对应的下标中。

接下来就是Q次操作了,从1到Q进行枚举,每次的操作类型是op,如果op为2,直接输出对应的ans,因为排序是我们已经进行过的操作,否则如果是1的话,我们就要将对应x的下标中val改为v,然后利用一个中间变量tmp存下修改后的下标为p的结构体,并将从下标为x的结构体开始,挨着交换到n,然后将n令为tmp再从后到前枚举进行排序以便用于下一步的操作,并将排完序之后的大小顺序利用ans数组来进行更新。

这个思路确实很难想,我想多数的读者和我一样都是想的第一个思想也就是直接模拟,希望读者仔细体会第二段代码,有所收获。

如果读者觉得以上的讲解有用,如果不嫌麻烦的话,希望能得到你的一个赞,万分感谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1335131.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内存之-LeakCanary

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、使用四、原理分析4.1 自动初始化4.1.1 初始化…

使用 fixture 机制重构 appium_helloworld

一、前置说明 在 pytest 基础讲解 章节,介绍了 pytest 的特性和基本用法,现在我们可以使用 pytest 的一些机制,来重构 appium_helloworld 。 appium_helloworld 链接: 编写第一个APP自动化脚本 appium_helloworld ,将脚本跑起来 代码目录结构: pytest.ini 设置: [pyt…

利用FLRIT恢复符号表---笔记

文章目录 FLIRT应用FLIRT签名创建FLIRT签名文件创建签名概述识别和获取静态库创建模式文件创建签名信息 FLIRT 在某些ELF文件中&#xff0c;IDA无法识别库函数的签名。就会导致IDA加载的函数全是sub_xxxx的形式&#xff0c;这给我们的逆向工程造成极大的困难。 这个时候就可以…

Python爬虫中的多线程、线程池

进程和线程的基本介绍 进程是一个资源单位&#xff0c;线程是一个执行单位&#xff0c;CPU调度线程来执行程序代码。 当运行一个程序时&#xff0c;会给这个程序分配一个内存空间&#xff0c;存放变量等各种信息资源&#xff0c;而这个内存空间可以说是一个进程&#xff0c; 一…

Linux文件系统与命令行

什么是命令行? 接收键盘命令并将其传给操作系统执行的程序(用于输入和管理命令的程序),统称命令行,也叫: Shell&#xff0c;几乎所有Linux发行版都提供了一个 Shell 程序,叫做: Bash (Bourne-Again Shell, 因为最初的 Shell 是由 Steve Bourne 编写的原始 Unix 程序, Again 表…

ChatGPT新增聊天存档功能,可构建自己的聊天数据库啦!

12月21日&#xff0c;OpenAI在社交平台宣布&#xff0c;ChatGPT新增存档功能&#xff0c;用户可以保存聊天记录而不必删除它们。 虽然这只是一个很小的功能&#xff0c;但对于科研、医疗、写作、金融、律师等&#xff0c;对文本使用频率较高的行业帮助巨大&#xff0c;可构建自…

Vue3设计目标和优化

vue3.0的设计目标是什么&#xff1f;做了哪些优化&#xff1f; Vue3的设计目标&#xff1a;更小、更快、更友好、优化方案 一、设计目标 Vue3之前我们会面临的许多问题&#xff1a; 随着功能的增长&#xff0c;复杂组件的代码变得越来越难以维护起来缺少一种比较【干净】的…

YACS(上海计算机学会竞赛平台)一星级题集——评委打分

题目描述 许多比赛在计算选手得分平均数的时候&#xff0c;都会先去掉一个最高得分&#xff0c;再去掉一个最低得分&#xff0c;这样可以避免极大值与极小值对平均值的影响。 给定 n 个数字 a[1]​,a[2]​,⋯,a[n]​&#xff0c;表示一个选手获得的分数&#xff0c;请根据上述…

【力扣】199.二叉树的右视图

看到这个题目的一瞬间&#xff0c;我想递归&#xff0c;必须用递归。最近被递归折磨的有点狠&#xff0c;但是我感觉我快要打败它了&#xff0c;就是现在稍稍有点处于劣势。不过没关系&#xff0c;来日方长不是。 法一&#xff1a;递归 题解&#xff1a; 之前想的就是先递归&…

【Vue3+TypeScript】快速上手_笔记

前言 1. Vue3简介 2020年9月18日&#xff0c;Vue.js发布版3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;n 经历了&#xff1a;4800次提交、40个RFC、600次PR、300贡献者 官方发版地址&#xff1a;Release v3.0.0 One Piece vuejs/core 截止2023年10月&#xf…

读文献、写论文时,有什么好用的软件或网站推荐?

高考志愿、考研保研、职业规划、简历优化&#xff0c;欢迎加入《猴哥成长营》&#xff01; https://www.yuque.com/jackpop/ulig5a/srnochggbsa2eltw?singleDoc 读文献、写论文对于绝大多数本科生、研究生、博士生都是必经之路。 当突然面对这样一项任务时&#xff0c;会觉得…

NVIDIA NCCL 源码学习(十二)- double binary tree

上节我们以ring allreduce为例看到了集合通信的过程&#xff0c;但是随着训练任务中使用的gpu个数的扩展&#xff0c;ring allreduce的延迟会线性增长&#xff0c;为了解决这个问题&#xff0c;NCCL引入了tree算法&#xff0c;即double binary tree。 double binary tree 朴素…

单位圆内接三角形的角是外接三角

证明 ∠ A P C 2 ∠ A B C ∠APC2∠ABC ∠APC2∠ABC ∴ ∴ ∴ 三角形内角和为180 $∵ \begin{cases} ∠ABP∠BAP∠APB180 \∠ABC∠BAC∠ACB180 \∠PAC∠PCA∠APC180 \end{cases} $ ∴ A P B P P C r ∴APBPPCr ∴APBPPCr ∵ ∵ ∵△PAB和△PAC为等腰三角形 ∴ ∴ ∴等腰三…

redis—String字符串

目录 前言 1.字符串数据类型 2.常见命令 3.典型应用场景 前言 字符串类型是Redis最基础的数据类型&#xff0c;关于字符串需要特别注意: 1)首先Redis中所有的键的类型都是字符串类型&#xff0c;而且其他几种数据结构也都是在字符串类似基础.上构建的&#xff0c;例如列表…

ROS xacro优化URDF

Xacro是ROS中的一个工具&#xff0c;用于简化URDF文件的编写。它的主要目的是构造更短、更易读的XML文件&#xff0c;同时保持与URDF的兼容性。 以下是Xacro的基本语法和用法&#xff1a; 1、属性设置和算数运算&#xff1a; 可以使用xacro:property来定义常量或变量&#xf…

《Git快速入门》Git分支

1.master、origin、origin/master 区别 首先搞懂git分支的一些名称区别&#xff1a; master &#xff1a; Git 的默认分支名字。它并不是一个特殊分支、跟其它分支完全没有区别。 之所以几乎每一个仓库都有 master 分支&#xff0c;是因为 git init 命令默认创建它&#xff0c…

利用markdown语法,写出数学公式以及常用符号【持续更新!!!】

1.希腊字母 数学表达式Markdown语法α\alphaβ\betaγ\gammaδ\deltaε\epsilonζ\zetaη\etaθ\thetaι\iotaκ\kappaλ\lambdaμ\muν\nuξ\xiο\omicronπ\piρ\rhoσ\sigmaτ\tauυ\upsilonφ\phiχ\chiψ\psiω\omega 2.基本表达式 数学表达式Markdow语法xx^2y₁y_1∞\…

医学影像处理与智能医学:数据集资源和云端加速路径

医学影像处理识别是一种利用计算机技术影像进行识别、分析和处理的方法。它主要应用于医学影像学领域&#xff0c;如 X 射线、CT 扫描、MRI 和超声等。通过图像处理技术&#xff0c;可以对这些影像进行数字化处理&#xff0c;提取有用信息&#xff0c;辅助医生进行疾病诊断、治…

如何编写高效清晰的嵌入式C程序

作为嵌入式工程师&#xff0c;怎么写出效率高、思路清晰的C语言程序呢? 要用C语言的思维方式来进行程序的构架构建 要有良好的C语言算法基础&#xff0c;以此来实现程序的逻辑构架 灵活运用C语言的指针操作 虽然看起来以上的说法很抽象&#xff0c;给人如坠雾里的感觉&…

【Element】el-select下拉框实现选中图标并回显图标

一、背景 需求&#xff1a;在下拉框中选择图标&#xff0c;并同时显示图标和文字&#xff0c;以便用户可以直观地选择所需的图标。 二、功能实现 <template><div><el-table ref"table" :data"featureCustom2List" height"200"…