Luogu P1327 数列排序
来源:互联网 发布:淘宝店铺开通直播 编辑:程序博客网 时间:2024/06/15 09:52
Luogu 1372 数列排序
上午学校搞模拟赛的第一题——其实真的是够了……快排+二分能过,不过题解给的快排+数学方法看起来也不错,这里只说说我的做法:
题目描述给定一个数列{an},这个数列满足ai≠aj(i≠j),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换?输入输出格式输入格式:第一行,正整数n (n<=100,000)。以下若干行,一共n个数,用空格分隔开,表示数列{an},任意-231<ai<231。输出格式:只有一行,包含一个数,表示最少的交换次数。输入输出样例输入样例#1:88 23 4 16 77 -5 53 100输出样例#1:5
首先看题第一反应就是选择排序——为啥呢?除了桶排这个不需要交换的排序算法以外,选择排序是执行交换次数最少的排序,注意这里是交换顺序不是时间复杂度……
紧接着——有一个定理——用选择排序排序时交换次数就是最少的,也就是我们的输出,然而我觉着这个并不能证明……那么问题来了,选择排序时间复杂度为O(n^2)很明显100000的数据是妥妥的炸了,于是选择排序废了
继续下一个思路——还记得树状数组逆序对么?或者说还记得归并排序逆序对么?然而经过试验——或者是手动笔算,你会发现逆序对根本就是WA——也就是说最小交换次数又不是逆序对个数
没办法我们只好来自行模拟选择排序的过程……其实只是大概借鉴了一下选排的思路——首先我们Sort一遍把序列排好,当然要保存原来的序列,这里我用了r(其实是一开始用归并排序剩下来的r数组)
然后呢?按照选排的方法卡就行了——首先我们找到r[1],然后在排好序的a中找到对应的元素——假设是第k个元素——把r[1]与r[k]交换过来,cnt++——接着继续找r[2]……这时可以轻易地发现——a中元素单调递增,满足二分查找的性质,于是我们来写个二分查找解决查找k的步骤——总时间复杂度O(n log n)
然而通过模拟样例可以发现一个漏洞——就是我们只搜一遍还不行,因为r数组有可能根本没排序完成,于是我们来第二遍、第三遍,反正只要r排好序了就行,相当于我们完成了选排的任务,这时候写个While来判断r是否有序就好啦,别忘了判断是否是第一个first,具体看代码自己看一下就好啦。
下面贴上AC代码——
#include <cstdio>#include <algorithm>using namespace std;int a[300000],r[300000],n,t,i,cnt,k;bool b=false,first;int find(int num){ int l=1,r=n,mid; while (l!=r) { mid=(l+r)>>1; if (a[mid]>=num) r=mid; else l=mid+1; } return l;}int main(){ freopen("seqsort.in","r",stdin); freopen("seqsort.out","w",stdout); scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%d",&a[i]); r[i]=a[i]; } sort(a+1,a+n+1); while (!b) { first=true; for (i=1;i<=n;i++) { k=find(r[i]); if (k!=i) { b=false; t=r[i]; r[i]=r[k]; r[k]=t; cnt++; } else if (first) { b=true; first=false; } else b=b&&true; } } printf("%d",cnt); fclose(stdin); fclose(stdout); return 0;}
- Luogu P1327 数列排序
- luogu P2401 不等数列
- luogu P1182 数列分段Section II
- luogu P1155 双栈排序
- [luogu]P1090合并排序-堆
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- 数列排序
- Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法
- 利用jquery给指定的table动态添加行、删除行
- Struts标签库详解,非常好的Struts标签详解
- 初记
- 1041. 考试座位号(15)
- Luogu P1327 数列排序
- 【Java基础之一】Java Classloader机制解析
- socket编程中select的使用
- 文章标题
- ubuntu手记
- JSTL 核心标签库
- Git工具连接GitHub(Windows配置篇)
- 十步开发第一个QNX Neutrino 程序
- Node.js中的HTTP模块