2075:【21CSPJ普及组】插入排序(sort)

时间限制: 1000 ms         内存限制: 524288 KB
提交数: 1547     通过数: 335

【题目描述】

插入排序是一种非常常见且简单的排序算法。小 Z 是一名大一的新生,今天 H 老师刚刚在上课的时候讲了插入排序算法。

假设比较两个元素的时间为 O(1)O(1),则插入排序可以以 O(n2)O(n2) 的时间复杂度完成长度为 nn 的数组的排序。不妨假设这 nn 个数字分别存储在 a1a1, a2a2, · · · , anan 之中,则如下伪

代码给出了插入排序算法的一种最简单的实现方式:

这下面是 C/C++ 的示范代码

for (int i = 1; i <= n; i++)for (int j = i; j>=2; j‐‐)if ( a[j] < a[j‐1] ){int t = a[j‐1];a[j‐1] = a[j];a[j] = t;}

这下面是 Pascal 的示范代码

for i:=1 to n dofor j:=i downto 2 doif a[j]<a[j‐1] thenbegint:=a[i];a[i]:=a[j];a[j]:=t;end;

为了帮助小 Z 更好的理解插入排序,小 Z 的老师 H 老师留下了这么一道家庭作业:

H 老师给了一个长度为 nn 的数组 aa,数组下标从 11 开始,并且数组中的所有元素均为非负整数。小 Z 需要支持在数组 aa 上的 Q 次操作,操作共两种,参数分别如下:

1 x v: 这是第一种操作,会将 aa 的第 xx 个元素,也就是 axax 的值,修改为 vv。保证1≤x≤n1≤x≤n, 1≤v≤1091≤v≤109。注意这种操作会改变数组的元素,修改得到的数组会被保留,也会影响后续的操作。

2 x: 这是第二种操作,假设 H 老师按照上面的伪代码对 aa 数组进行排序,你需要告诉 H 老师原来 aa 的第 xx 个元素,也就是 axax,在排序后的新数组所处的位置。保证

1≤x≤n1≤x≤n。注意这种操作不会改变数组的元素,排序后的数组不会被保留,也不会影响后续的操作。

H 老师不喜欢过多的修改,所以他保证类型 11 的操作次数不超过 50005000。

小 Z 没有学过计算机竞赛,因此小 Z 并不会做这道题。他找到了你来帮助他解决这个问题。

【输入】

输入的第一行包含两个正整数 nn, QQ,表示数组长度和操作次数。保证 1≤n≤8,000,1≤Q≤2×1051≤n≤8,000,1≤Q≤2×105。

输入的第二行包含 nn 个空格分隔的非负整数,其中第 ii 个非负整数表示 aiai。保证1≤ai≤1091≤ai≤109。

接下来 QQ 行,每行 22 ∼ 33 个正整数,表示一次操作,操作格式见题目描述。

【输出】

对于每一次类型为 22 的询问,输出一行一个正整数表示答案。

【输入样例】

3 4
3 2 1
2 3
1 3 2
2 2
2 3

【输出样例】

1
1
2

【提示】

【样例 1 解释】

在修改操作之前,假设 H 老师进行了一次插入排序,则原序列的三个元素在排序结束后所处的位置分别是 3, 2, 1。

注意虽然此时 a2=a3a2=a3,但是我们不能将其视为相同的元素。

【样例 2】

见选手目录下的 sort/sort2.in 与 sort/sort2.ans。

该测试点数据范围同测试点 1 ∼ 2。

【样例 3】

见选手目录下的 sort/sort3.in 与 sort/sort3.ans。

该测试点数据范围同测试点 3 ∼ 7。

【样例 4】

见选手目录下的 sort/sort4.in 与 sort/sort4.ans。

该测试点数据范围同测试点 12 ∼ 14。

【数据范围】

对于所有测试数据,满足 1≤n≤8,0001≤n≤8,000, 1≤Q≤2×1051≤Q≤2×105, 1≤x≤n1≤x≤n, 1≤v1≤v, ai≤109ai≤109。

对于所有测试数据,保证在所有 QQ 次操作中,至多有 50005000 次操作属于类型一。

各测试点的附加限制及分值如下表所示。

测试点 n Q 特殊性质
1,2,3,4 ≤ 10 ≤ 10
5,6,7,8,9 ≤ 300 ≤ 300
10,11,12,13 ≤ 1, 500 ≤ 1, 500
14,15,16 ≤ 8, 000 ≤ 8, 000 保证所有输入的 ai, v 互不相同
17,18,19
20,21,22 ≤ 2 × 105 保证所有输入的 ai, v 互不相同
23,24,25

本题目评测默认开启-O2

代码:

52分:

未通过

测试点 结果 内存 时间
测试点1 答案正确 936KB 1MS
测试点2 答案正确 940KB 2MS
测试点3 答案正确 948KB 2MS
测试点4 答案正确 940KB 2MS
测试点5 答案正确 948KB 9MS
测试点6 答案正确 944KB 10MS
测试点7 答案正确 936KB 10MS
测试点8 答案正确 932KB 10MS
测试点9 答案正确 936KB 11MS
测试点10 答案正确 928KB 692MS
测试点11 答案正确 920KB 826MS
测试点12 答案正确 932KB 791MS
测试点13 答案正确 932KB 809MS
测试点14 运行超时 824KB 1000MS
测试点15 运行超时 824KB 1001MS
测试点16 运行超时 828KB 997MS
测试点17 运行超时 804KB 1001MS
测试点18 运行超时 828KB 997MS
测试点19 运行超时 808KB 1001MS
测试点20 运行超时 840KB 997MS
测试点21 运行超时 824KB 997MS
测试点22 运行超时 828KB 998MS
测试点23 运行超时 832KB 997MS
测试点24 运行超时 812KB 1001MS
测试点25 运行超时 828KB 997MS
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 10010;//p[i]表示排序后i位置的数在原数组p[i]位置
//np[i]表示原数组i位置的数在排序后的数组np[i]
int a[N], b[N], p[N], np[N], bp[N], bnp[N];
int n, q;int main()
{   cin >> n >> q;for(int i = 1; i <= n; i ++){scanf("%d", &a[i]);np[i] = p[i] = i;}   while(q --){int op, x, v;scanf("%d%d", &op, &x);if(op == 1){scanf("%d", &v);a[x] = v;          }else{//备份memcpy(b, a, sizeof a);memcpy(bp, p, sizeof p);memcpy(bnp, np, sizeof np);            //插入排序for(int i = 2; i <= n; i ++)for(int j = i; j > 1 && a[j] < a[j - 1]; j --){swap(a[j], a[j - 1]);np[p[j]] = j - 1, np[p[j - 1]] = j;swap(p[j], p[j - 1]);}printf("%d\n", np[x]);  //还原          memcpy(a, b, sizeof b);memcpy(p, bp, sizeof bp);memcpy(np, bnp, sizeof bnp);}}
}

76分:

#include<bits/stdc++.h>
using namespace std;
int a[10010],n,Q;
int main()
{scanf("%d%d",&n,&Q);for(int i=1;i<=n;i++)scanf("%d",&a[i]);int f,x,v;for(int i=1;i<=Q;i++){scanf("%d",&f);if(f==1){//第一种操作 scanf("%d%d",&x,&v);a[x]=v;}else{//第二种操作 scanf("%d",&x);int c=0,d=0;for(int j=1;j<x;j++)//前移c位 if(a[j]>a[x])c++;for(int j=x+1;j<=n;j++)//后移d位 if(a[j]<a[x])d++;printf("%d\n",x-c+d);//输出最终位置 }}return 0;
}

未通过

测试点 结果 内存 时间
测试点1 答案正确 612KB 1MS
测试点2 答案正确 612KB 2MS
测试点3 答案正确 596KB 2MS
测试点4 答案正确 600KB 2MS
测试点5 答案正确 612KB 2MS
测试点6 答案正确 604KB 2MS
测试点7 答案正确 604KB 2MS
测试点8 答案正确 608KB 2MS
测试点9 答案正确 612KB 2MS
测试点10 答案正确 608KB 3MS
测试点11 答案正确 616KB 3MS
测试点12 答案正确 604KB 3MS
测试点13 答案正确 616KB 3MS
测试点14 答案正确 628KB 26MS
测试点15 答案正确 636KB 26MS
测试点16 答案正确 628KB 26MS
测试点17 答案正确 640KB 25MS
测试点18 答案正确 632KB 26MS
测试点19 答案正确 640KB 26MS
测试点20 运行超时 608KB 1003MS
测试点21 运行超时 616KB 987MS
测试点22 运行超时 612KB 993MS
测试点23 答案正确 636KB 1000MS
测试点24 运行超时 620KB 1002MS
测试点25 运行超时 612KB 991MS

100分:

#include <bits/stdc++.h>
using namespace std;const int maxn=8005;
int n,Q;
int o2x[maxn]; //o2x[i] represents the position in the new sequencestruct node {int v,id; //p[i].id represents the original sequence
} p[maxn];bool cmp(node x,node y) {if(x.v!=y.v) return x.v<y.v;return x.id<y.id;
}int main() {scanf("%d%d",&n,&Q);for(int i=1; i<=n; i++) {scanf("%d",&p[i].v);p[i].id=i;}sort(p+1,p+1+n,cmp);for(int i=1; i<=n; i++) o2x[p[i].id]=i;while(Q--) {int op;scanf("%d",&op);if(op==1) {int x,y;scanf("%d%d",&x,&y);p[o2x[x]].v=y;for(int j=o2x[x]; j>=2; j--)if(p[j].v<p[j-1].v || p[j].v==p[j-1].v&&p[j].id<p[j-1].id) {swap(p[j],p[j-1]);o2x[p[j].id]=j;o2x[p[j-1].id]=j-1;} else break;for(int j=o2x[x]; j<=n-1; j++)if(p[j].v>p[j+1].v || p[j].v==p[j+1].v&&p[j].id>p[j+1].id) {swap(p[j],p[j+1]);o2x[p[j].id]=j;o2x[p[j+1].id]=j+1;} else break;} else {int x;scanf("%d",&x);printf("%d\n",o2x[x]);}}return 0;
}

通过

测试点 结果 内存 时间
测试点1 答案正确 600KB 1MS
测试点2 答案正确 600KB 2MS
测试点3 答案正确 604KB 1MS
测试点4 答案正确 608KB 1MS
测试点5 答案正确 608KB 2MS
测试点6 答案正确 604KB 2MS
测试点7 答案正确 604KB 2MS
测试点8 答案正确 612KB 2MS
测试点9 答案正确 604KB 2MS
测试点10 答案正确 624KB 3MS
测试点11 答案正确 628KB 3MS
测试点12 答案正确 628KB 3MS
测试点13 答案正确 628KB 3MS
测试点14 答案正确 692KB 32MS
测试点15 答案正确 692KB 31MS
测试点16 答案正确 688KB 33MS
测试点17 答案正确 684KB 33MS
测试点18 答案正确 696KB 33MS
测试点19 答案正确 696KB 33MS
测试点20 答案正确 684KB 91MS
测试点21 答案正确 684KB 93MS
测试点22 答案正确 684KB 95MS
测试点23 答案正确 688KB 89MS
测试点24 答案正确 692KB 93MS
测试点25 答案正确 684KB 94MS

【信息学奥赛一本通】2075:【21CSPJ普及组】插入排序(sort)相关推荐

  1. 信息学奥赛一本通(C++版)NOIP提高组(1820-1829)

    信息学奥赛一本通(C++版)NOIP提高组目录 //1820 [题目描述] 我们可以用这样的方式来表示一个十进制数:将每个阿拉伯数字乘以一个以该数字所 处位置的(值减1)为指数,以10为底数的幂之和的 ...

  2. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  3. 信息学奥赛一本通(C++版) 网站补充题目

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 网站补充题目 http://ybt.ssoier ...

  4. 信息学奥赛一本通在线提交地址

    信息学奥赛一本通 1 C++语言入门 1.1 综合 1.1.1 P1458 地球人口承载力估计 正确: 770 提交: 1794 比率: 42.92 % 1.1.2 P1686 Hello, Worl ...

  5. 信息学奥赛一本通(C++版) 第二部分 基础算法 第九章 动态规划

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 第二部分 基础算法 第九章 动态规划 第一节 动 ...

  6. 《信息学奥赛一本通 提高篇》

    提高篇 第一部分 基础算法 第1章 贪心算法 提高篇 第一部分 基础算法 第1章 贪心算法_青少年趣味编程-CSDN博客 提高篇 第一部分 基础算法 第1章 贪心算法 提高篇 第一部分 基础算法 第1 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂

    信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂 https://blog.csdn.net/mrcrack/article/details/82846727 快速幂取模算法如何实现? h ...

  8. 信息学奥赛一本通(1101:不定方程求解)

    1101:不定方程求解 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 18175     通过数: 14383 [题目描述] 给定正整数a,b,c.求不定方程 a ...

  9. 信息学奥赛一本通(基础算法与数据结构-题解汇总目录)

    信息学奥赛一本通(C++版)在线评测系统 基础(二)基础算法   更新中...... 第一章高精度计算 1307[例1.3]高精度乘法 1308[例1.5]高精除 1309[例1.6]回文数(Noip ...

最新文章

  1. django框架 day06
  2. java postconstruct_java的@PostConstruct注解
  3. 物联网将如何改善社会运行效率?
  4. ENVI学习总结(十)——遥感图像监督分类
  5. google code 代码托管 用git创建仓库
  6. WWW15年:改变世界的15个网站
  7. Zint 库:Zint库的编译及使用(二维码QrCode生码),MFC/VC使用实例
  8. L1-087 机工士姆斯塔迪奥
  9. 下载Windows ARM版本记录
  10. CSDN写文章——不要使用默认标题
  11. 阿里云域名实名认证状态查询
  12. OpenGauss的内存优化表MOT
  13. c语言选择结构程序设计实验报告6,c语言-选择结构程序设计实验报告4.doc
  14. Go-包管理(管理工具对比及go mod的使用)
  15. Docker: windows下跑windows镜像
  16. i510400f和i59400f差距 i5 10400f和i5 9400f哪个好
  17. 采用开源工具学习51单片机
  18. JQ JS分页序号连续
  19. Karaf教程第2部分使用Configuration Admin服务
  20. 计算机辅助设计在口腔医学中的应用,快速原型技术在口腔医学中的应用.doc

热门文章

  1. Unity 网络请求
  2. 三线制PT100测正温(篇一)
  3. 用Python向MongoDB中插入大csv文件
  4. java与es8实战之五:SpringBoot应用中操作es8(带安全检查:https、账号密码、API Key)
  5. vSphere Client连接主机提示远程服务器响应时间过长
  6. Itest(爱测试),最懂测试人的开源测试管理软件隆重发布
  7. ue4创建一个游戏模式Game mode
  8. java背单词页面_简易Web背单词软件 #01# 当前功能
  9. 国内CDN加速哪个好?
  10. 教你玩转商业字体设计