信息学奥赛一本通 2075:【21CSPJ普及组】插入排序(sort) | 洛谷 P7910 [CSP-J 2021] 插入排序

【题目链接】

ybt 2075:【21CSPJ普及组】插入排序(sort)
洛谷 P7910 [CSP-J 2021] 插入排序

【题目考点】

1. 排序:
  • 插入排序
    插入排序示例:
#include <bits/stdc++.h>
using namespace std;
int main()
{int n, a[100005];cin >> n;for(int i = 1; i <= n; ++i)cin >> a[i];for(int i = 2; i <= n; ++i)//将第i个数字插入有序序列{for(int j = i; j > 1; j--)//j指向待插入数字{if(a[j] < a[j - 1])swap(a[j], a[j - 1]);elsebreak;}}for(int i = 1; i <= n; ++i)cout << a[i] << ' ';return 0;
}
  • 索引排序
    设原数组第i元素为a[i],经过排序后的目标数组的第i元素为t[i]
    索引数组ind:ind[i]表示t[i]在数组a中的下标。
    即有目标数组第i元素t[i]a[ind[i]]
    若要交换目标数组中两个元素swap(t[i], t[j]),索引数组的变化为swap(ind[i], ind[j])
    实际上代码中不存在目标数组t,只保存索引数组ind。对索引数组进行排序,可以在不改变原数组a的情况下得到排序后的数组。
    例:插入排序的索引排序
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int main()
{int n, a[N], ind[N];cin >> n;for(int i = 1; i <= n; ++i){cin >> a[i];ind[i] = i;//初始时t[i] == a[i] }for(int i = 2; i <= n; ++i)//将第i个数字插入有序序列for(int j = i; j > 1; j--)//j指向待插入数字{if(a[ind[j]] < a[ind[j - 1]])swap(ind[j], ind[j - 1]);elsebreak;}for(int i = 1; i <= n; ++i)cout << a[ind[i]] << ' ';return 0;
}

【解题思路】

假想存在排序后的目标数组s,设数组sa为索引数组,表示sa[i]排序后下标i的元素s[i]在数组a中的下标。也就是s[i] == a[sa[i]]
设数组as,as[i]表示a[i]在排序后的s数组中的下标,也就是a[i] == s[as[i]]
当i为sa[i]时,有a[sa[i]] == s[as[sa[i]]] == s[i],因此有as[sa[i]] == i
sa与as保存的就是原数组a与目标数组s之间的两个方向的映射关系。

如果s[i]要与s[j]的值发生交换,那么就是从s[i] == a[sa[i]]同时s[j] == a[sa[j]]变为s[i] == a[sa[j]]同时s[j] == a[sa[i]],只需要交换sa[i]sa[j]的值即可。
而后根据as[sa[i]] == i,重新设as[sa[i]]as[sa[j]]的值。因此要完成交换s[i]s[j],需要运行:

void Swap(int i, int j)
{ swap(sa[i], sa[j]);as[sa[i]] = i;as[sa[j]] = j;
}

主函数中,首先输入a数组,初始状态下s数组与a数组相同,满足s[i] == a[i],因此有sa[i] = i; as[i] = i;
先根据题意,使用索引数组完成插入排序,注意交换元素时需要使用我们定义的Swap函数。
而后进行q次操作

  • 如果要改变元素,输入x,v。先将a[x]变为v,而后观察a[x]是变大了还是变小了。

    • 如果满足v > a[x],变大了,则应该把a[x]对应在目标数组中的值s[as[x]]向后移动。
      j从as[x]开始,不断变大,向后遍历s数组,直到j为n-1。
      j向后移动的条件为:当前数字s[j]比后面的数字s[j+1]更大,或者在当前数字s[j]与后面数字s[j+1]相等的情况下,当前数字s[j]在原数组中的下标sa[j]比后面数字s[j+1]在原数组中的下标sa[j+1]更大。因为插入排序是稳定的排序,排序后相等数值元素的相对顺序不变。对于相同的数值,在原数组中下标更大的元素应该排在后面。
      只要满足这一条件,就交换s[j]s[j+1],否则结束循环。该过程中的交换操作要使用我们定义的Swap函数,实际是由索引数组sa与as完成交换。

    • 否则如果满足v <= a[x],变小了,则应该把a[x]对应在目标数组中的值s[as[x]]向前移动。
      j从as[x]开始,不断变小,向前遍历s数组,直到j为2。
      j向前移动的条件为:当前数字s[j]比前面的数字s[j-1]更小,或者在当前数字s[j]与前面数字s[j-1]相等的情况下,当前数字s[j]在原数组中的下标sa[j]比前面数字s[j-1]在原数组中的下标sa[j-1]更小。因为插入排序是稳定的排序,排序后相等数值元素的相对顺序不变。对于相同的数值,在原数组中下标更小的元素应该排在前面。
      只要满足这一条件,就交换s[j]s[j-1],否则结束循环。该过程中的交换操作要使用我们定义的Swap函数,实际是由索引数组sa与as完成交换。

  • 如果要查询原数组第x元素a[x]在s数组中的下标,就是as[x]

【题解代码】

解法1:
#include<bits/stdc++.h>
using namespace std;
#define N 8005
int a[N];
int sa[N];//sa[i]:排序后下标i的元素在数组a中的下标 
int as[N];//as[i]:a[i]在排序后的下标 
void Swap(int i, int j)
{//排序后第i元素第j元素交换 swap(sa[i], sa[j]);as[sa[i]] = i;as[sa[j]] = j;
}
int main()
{int n, q, t, x, v, px;cin >> n >> q; for(int i = 1; i <= n; ++i){cin >> a[i];sa[i] = i;as[i] = i;}for(int i = 1; i <= n; ++i)for(int j = i; j >= 2; --j)if(a[sa[j]] < a[sa[j-1]])Swap(j, j-1);for(int i = 1; i <= q; ++i){//由于插入排序是稳定的,如相等,下标大的在右边 cin >> t;if(t == 1){cin >> x >> v;if(v > a[x])//变大,a[x]右移 {a[x] = v;for(int j = as[x]; j <= n - 1; ++j){if(a[sa[j]] > a[sa[j+1]] || a[sa[j]] == a[sa[j+1]] && sa[j] > sa[j+1])Swap(j, j+1);elsebreak;}}else{//变小,a[x]左移a[x] = v;for(int j = as[x]; j >= 2; --j){if(a[sa[j]] < a[sa[j-1]] || a[sa[j]] == a[sa[j-1]] && sa[j] < sa[j-1])Swap(j, j-1);elsebreak;}}}else{cin >> x;cout << as[x] << endl;}		}return 0;
}

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

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

相关文章

leetcode201 Bitwise AND of Numbers Range

求区间内的数字全部与之后的结果 其实可以观察到&#xff0c;只会留下从高到低&#xff0c;第一个不同位之前的 12 ---- 110011 ---- 101110 ---- 10109 ---- 10018 ---- 10007 ---- 01116 ---- 01105 ---- 0101像这种一位都不会相同 因此代码可以直接删除最低位的1&…

表格内日期比较计算

需求&#xff1a;在表格中新增数据&#xff0c;计算开始日期中最早的和结束日期中最晚的&#xff0c;回显到下方。 <el-formref"formRef":model"ruleForm":rules"rules"style"margin-top: 20px;"label-position"top">…

博弈论——斯塔克尔伯格模型(Stackelberg model)

斯塔克尔伯格模型(Stackelberg model) 0 前言 前两篇文章中我们提到了连续产量的古诺模型以及可以应用于古诺模型的反应函数。 博弈论——连续产量古诺模型 博弈论——反应函数 古诺模型中&#xff0c;我们强调了: &#xff08;1&#xff09;两个厂商是同时决策的,即博弈只有…

cargo 使用国内的镜像

打开或新建 ~/.cargo/config 文件 vim ~/.cargo/config修改为 中国科学技术大学镜像服务器 [source.crates-io] registry "https://github.com/rust-lang/crates.io-index" replace-with ustc [source.ustc] registry "git://mirrors.ustc.edu.cn/crates.i…

python爬虫基于管道持久化存储操作

文章目录 基于管道持久化存储操作scrapy的使用步骤1.先转到想创建工程的目录下&#xff1a;cd ...2.创建一个工程3.创建之后要转到工程目录下4.在spiders子目录中创建一个爬虫文件5.执行工程setting文件中的参数 基于管道持久化存储的步骤&#xff1a;持久化存储1&#xff1a;保…

IntelliJ IDEA 常用快捷键一览表

目录 1-IDEA的日常快捷键 第1组&#xff1a;通用型 第2组&#xff1a;提高编写速度&#xff08;上&#xff09; 第3组&#xff1a;提高编写速度&#xff08;下&#xff09; 第4组&#xff1a;类结构、查找和查看源码 第5组&#xff1a;查找、替换与关闭 第6组&#xff1a…

JavaScript关于==隐式转换的判断

一.以下数据类型转布尔值&#xff0c;以下均返回true&#xff1a; 1. 非空字符串 2. 非零数值 3. 数组 4. 对象 5. 函数 二.判断方法: 1. 前提条件: 1) 相等操作符&#xff0c;不同数据类型会根据一定规则转换为同一数据类型再比较 注意: (这里指的数据类型也可能需要转…

Win11下无法打开丛林之狐,提示未检测到DirectX 8.1

新装的win11系统&#xff0c;打开丛林之狐提示未检测到DirectX 8.1. 运行dxdiag检查DirectX版本&#xff1a; DX版本已经是12了&#xff1a; 最终参考了这篇文章解决了&#xff1a; 罪恶都市出现XX-directx version 8.1处理方法 - 知乎 控制面板 > 程序 > 启用或关闭Wi…

请求代理转发(三)

请求代理转发(三) 书接上回&#xff0c;在内部服务代理其他服务时&#xff0c; 这次使用 webclient 作为请求客户端 import static org.springframework.web.reactive.HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE;Slf4j RestController public class ProxyControl…

【Rust】操作日期与时间

目录 介绍 一、计算耗时 二、时间加减法 三、时区转换 四、年月日时分秒 五、时间格式化 介绍 Rust的时间操作主要用到chrono库&#xff0c;接下来我将简单选一些常用的操作进行介绍&#xff0c;如果想了解更多细节&#xff0c;请查看官方文档。 官方文档&#xff1a;chr…

小谈设计模式(6)—依赖倒转原则

小谈设计模式&#xff08;6&#xff09;—依赖倒转原则 专栏介绍专栏地址专栏介绍 依赖倒转原则核心思想关键点分析abc 优缺点分析优点降低模块间的耦合度提高代码的可扩展性便于进行单元测试 缺点增加代码的复杂性需要额外的设计和开发工作 Java代码实现示例分析 总结 专栏介绍…

PDF文件压缩软件 PDF Squeezer mac中文版​软件特点

PDF Squeezer mac是一款macOS平台上的PDF文件压缩软件&#xff0c;可以帮助用户快速地压缩PDF文件&#xff0c;从而减小文件大小&#xff0c;使其更容易共享、存储和传输。PDF Squeezer使用先进的压缩算法&#xff0c;可以在不影响文件质量的情况下减小文件大小。 PDF Squeezer…

7、Docker网络

docker网络模式能干嘛&#xff1f; 容器间的互联和通信以及端口映射 容器IP变动时候可以通过服务名直接网络通信而不受到影响 docker 网络模式采用的是桥接模式&#xff0c;当我们创建了一个容器后docker网络就会帮我们创建一个虚拟网卡&#xff0c;这个虚拟网卡和我们的容器网…

【数据结构】队列和栈

大家中秋节快乐&#xff0c;玩了好几天没有学习&#xff0c;今天分享的是栈以及队列的相关知识&#xff0c;以及栈和队列相关的面试题 1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作…

UG\NX二次开发 通过点云生成曲面 UF_MODL_create_surf_from_cloud

文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 感谢粉丝订阅 感谢 Rlgun 订阅本专栏,非常感谢。 简介 有网友想做一个通过点云生成曲面的程序,我们也试一下 效果 代码 #include "me.hpp" /*HEAD CREATE_SURF_FROM_CLOUD CCC UFUN */

安全学习_开发相关_Java第三方组件Log4jFastJSON及相关安全问题简介

文章目录 JNDI&#xff1a;(见图) Java-三方组件-Log4J&JNDILog4J&#xff1a;Log4j-组件安全复现使用Log4j Java-三方组件-FastJsonFastJson&#xff1a;Fastjson-组件安全复现对象转Json(带类型)Json转对象Fastjson漏洞复现&#xff08;大佬文章 JNDI&#xff1a;(见图) …

数据结构与算法之字典: Leetcode 1. 两数之和 (Typescript版)

两数之和 https://leetcode.cn/problems/two-sum/ 描述 给定一个整数数组nums和一个整数目标值target&#xff0c;请你在该数组中找出和为目标值target的那两个整数&#xff0c;并返回它们的数组下标你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在…

C# Task任务详解

文章目录 前言Task返回值无参返回有参返回 async和await返回值await搭配使用Main async改造 Task进阶Task线程取消测试用例超时设置 线程暂停和继续测试用例 多任务等最快多任务全等待 结论 前言 Task是对于Thread的封装&#xff0c;是极其优化的设计&#xff0c;更加方便了我…

PL/SQL+cpolar公网访问内网Oracle数据库

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

php中判断指定字符串是否包含指定字符的封装函数

在 PHP 中&#xff0c;你可以使用内置的字符串函数 strpos() 来判断一个字符串是否包含指定的字符或子字符串。以下是一个简单的封装函数&#xff0c;它使用 strpos() 来判断指定字符串是否包含指定字符&#xff0c;并返回一个布尔值。 function stringContains($string, $cha…