【信息学奥赛一本通】2075:【21CSPJ普及组】插入排序(sort)
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)相关推荐
- 信息学奥赛一本通(C++版)NOIP提高组(1820-1829)
信息学奥赛一本通(C++版)NOIP提高组目录 //1820 [题目描述] 我们可以用这样的方式来表示一个十进制数:将每个阿拉伯数字乘以一个以该数字所 处位置的(值减1)为指数,以10为底数的幂之和的 ...
- 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题
第1章 快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章 素数 第 3 章 约数 第 4 章 同余问题 第 5 章 矩阵乘法 第 6 章 ...
- 信息学奥赛一本通(C++版) 网站补充题目
总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 网站补充题目 http://ybt.ssoier ...
- 信息学奥赛一本通在线提交地址
信息学奥赛一本通 1 C++语言入门 1.1 综合 1.1.1 P1458 地球人口承载力估计 正确: 770 提交: 1794 比率: 42.92 % 1.1.2 P1686 Hello, Worl ...
- 信息学奥赛一本通(C++版) 第二部分 基础算法 第九章 动态规划
总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 第二部分 基础算法 第九章 动态规划 第一节 动 ...
- 《信息学奥赛一本通 提高篇》
提高篇 第一部分 基础算法 第1章 贪心算法 提高篇 第一部分 基础算法 第1章 贪心算法_青少年趣味编程-CSDN博客 提高篇 第一部分 基础算法 第1章 贪心算法 提高篇 第一部分 基础算法 第1 ...
- 信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂
信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂 https://blog.csdn.net/mrcrack/article/details/82846727 快速幂取模算法如何实现? h ...
- 信息学奥赛一本通(1101:不定方程求解)
1101:不定方程求解 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 18175 通过数: 14383 [题目描述] 给定正整数a,b,c.求不定方程 a ...
- 信息学奥赛一本通(基础算法与数据结构-题解汇总目录)
信息学奥赛一本通(C++版)在线评测系统 基础(二)基础算法 更新中...... 第一章高精度计算 1307[例1.3]高精度乘法 1308[例1.5]高精除 1309[例1.6]回文数(Noip ...
最新文章
- django框架 day06
- java postconstruct_java的@PostConstruct注解
- 物联网将如何改善社会运行效率?
- ENVI学习总结(十)——遥感图像监督分类
- google code 代码托管 用git创建仓库
- WWW15年:改变世界的15个网站
- Zint 库:Zint库的编译及使用(二维码QrCode生码),MFC/VC使用实例
- L1-087 机工士姆斯塔迪奥
- 下载Windows ARM版本记录
- CSDN写文章——不要使用默认标题
- 阿里云域名实名认证状态查询
- OpenGauss的内存优化表MOT
- c语言选择结构程序设计实验报告6,c语言-选择结构程序设计实验报告4.doc
- Go-包管理(管理工具对比及go mod的使用)
- Docker: windows下跑windows镜像
- i510400f和i59400f差距 i5 10400f和i5 9400f哪个好
- 采用开源工具学习51单片机
- JQ JS分页序号连续
- Karaf教程第2部分使用Configuration Admin服务
- 计算机辅助设计在口腔医学中的应用,快速原型技术在口腔医学中的应用.doc