题目

Given any permutation of the numbers {0, 1, 2,…, N-1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:

Swap(0, 1) => {4, 1, 2, 0, 3}

Swap(0, 3) => {4, 1, 2, 3, 0}

Swap(0, 4) => {0, 1, 2, 3, 4}

Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.

Input Specification:

Each input file contains one test case, which gives a positive N (<=105) followed by a permutation sequence of {0, 1, …, N-1}. All the numbers in a line are separated by a space.

Output Specification:

For each case, simply print in a line the minimum number of swaps need to sort the given permutation.

Sample Input:

10 3 5 7 2 6 4 9 0 8 1

Sample Output:

9

题目分析

已知N个任意排列的数字,要求最少交换次数对其排序(排序过程只能使用0与其他数字交换位置

解题思路

  1. 贪心算法:如果当前数字0在i号位置,找到数字i当前所处位置,将数字0和i交换

证明:

由于0必须参加交换操作,因此通过该策略,每步总是可以将一个非零的数回归本位。如果用0与其他不是该位置编号的数进行交换,显然会产生一个无效操作,因为后续操作中还是需要将刚才交换的数换回本位,因此该策略能将无效操作次数(与0交换的数没有回归本位的次数)降到最小,于是最优。

第一步: 0在7号位,因此将0与7交换,得到序列3502649781

第二步: 0在2号位,因此将0与2交换,得到序列3520649781

第三步: 0在3号位,因此将0与3交交换,得到序列0523649781

第四步: 0在0号位,因此将0与一个还未在本位的数字5交换,得到序列得到序列5023649781

第五步: 0在1号位,因此将0与1交换,得到序列5123649780

第六步: 0在9号位,因此将0与9交换,得到序列5123640789

第七步: 0在6号位,因此将0与6交换,得到序列5123046789

第八步: 0在4号位,因此将0与4交换,得到序列5123406789

第九步: 0在5号位,因此将0与5交换,得到序列0123456789

此时序列有序,总交换次数为9次。

//style="background-color: #FF8C00;"

  1. 定义数组int pos[N],记录数字所在位置(如:pos[i],表示数字i在pos[i]的位置)
  2. 哨兵为数字0,pos[0]=0,不一定排序已完成
    • pos[0]==0,但是排序未完成,将0需要与不在本位的数字交换(因为如果0与已回到本位的数字交换会导致交换次数变多),定义数字k初始化为1,记录当前不在本位的最小数字(避免每次都循环遍历数组,查找未回到本位的数字(复杂度为O(n^2)有两个点会超时))
    • pos[0]==0,已完成排序(如何检测已完成排序?--定义变量left记录除0以外不在自己本位数字的个数,left=0表示排序完成)

注意点

  1. 当0回到本位时,并不一定保证数字都已回到本位。此时需要找到一个未在本位的数字与0进行交换(如果选择已在本位的数字与0交换会导致交换次数增多)

Code

Code 01

#include <iostream>
#include <string>
using namespace std;
int main(int argc, char * argv[]) {
int N,m,cnt=0;//cnt--总交换次数
scanf("%d",&N);
int pos[N]= {0};// pos[i]--数字i的位置为pos[i]
int left=N-1; // 除0以外不在本位的数字
for(int i=0; i<N; i++) {
scanf("%d", &m);
pos[m]=i; // 数字m在位置i
if(m==i&&m!=0)left--; // 除0以外已在本位,left--
}
int k=1; //当前最小不在本位的数字,避免0在本位但排序未完成时,每次都需要遍历数组找未在本位的数字(复杂度O(n^2)会超时)
while(left>0) {
if(pos[0]==0) { //如果排序未完成,0已回到本位,将0与最小不在本位的k进行互换
while(k<N) {
if(pos[k]!=k) { //如果k不在本位
swap(pos[0],pos[k]);
cnt++; //无需left++,因为k本来就不再本位,0在本位但是left记录的是非0不在本位的数字个数
break;
}
k++; //如果k在本位,向前找最小不在本位的k
}
}
while(pos[0]!=0) { //0不在本位
swap(pos[0],pos[pos[0]]);
left--; //有一个数字回归本位
cnt++;
}
}
printf("%d",cnt);
return 0;
}

Code 02

#include <iostream>
#include <string>
using namespace std;
int main(int argc, char * argv[]) {
int N,m,cnt=0;
scanf("%d",&N);
int pos[N]= {0};
for(int i=0; i<N; i++) {
scanf("%d", &m);
pos[m]=i;
}
for(int i=0; i<N; i++) { //个人理解,这里处理不是很好,因为已遍历过的i不能保证其已回到本位
if(pos[i]!=i) {
while(pos[0]!=0) {
swap(pos[0],pos[pos[0]]);
cnt++;
}
if(pos[i]!=i) {
swap(pos[0],pos[i]);
cnt++;
}
}
}
printf("%d",cnt);
return 0;
}

PAT Advanced 1067 Sort with Swap(0,*) (25) [贪⼼算法]的更多相关文章

  1. PAT甲题题解-1067. Sort with Swap(0,*) (25)-贪心算法

    贪心算法 次数最少的方法,即:1.每次都将0与应该放置在0位置的数字交换即可.2.如果0处在自己位置上,那么随便与一个不处在自己位置上的数交换,重复上一步即可.拿样例举例:   0 1 2 3 4 5 ...

  2. 1067. Sort with Swap(0,*) (25)【贪心】——PAT (Advanced Level) Practise

    题目信息 1067. Sort with Swap(0,*) (25) 时间限制150 ms 内存限制65536 kB 代码长度限制16000 B Given any permutation of t ...

  3. PAT 甲级 1067 Sort with Swap(0, i) (25 分)(贪心,思维题)*

    1067 Sort with Swap(0, i) (25 分)   Given any permutation of the numbers {0, 1, 2,..., N−1}, it is ea ...

  4. 1067. Sort with Swap(0,*) (25)

    时间限制 150 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Given any permutation of the num ...

  5. PAT (Advanced Level) 1067. Sort with Swap(0,*) (25)

    只对没有归位的数进行交换. 分两种情况: 如果0在最前面,那么随便拿一个没有归位的数和0交换位置. 如果0不在最前面,那么必然可以归位一个数字,将那个数字归位. 这样模拟一下即可. #include& ...

  6. PAT 1067. Sort with Swap(0,*)

    1067. Sort with Swap(0,*) (25)   Given any permutation of the numbers {0, 1, 2,..., N-1}, it is easy ...

  7. pat1067. Sort with Swap(0,*) (25)

    1067. Sort with Swap(0,*) (25) 时间限制 150 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue G ...

  8. 1067 Sort with Swap(0, i) (25 分)

    1067 Sort with Swap(0, i) (25 分) Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy ...

  9. PTA 1067 Sort with Swap(0, i) (贪心)

    题目链接:1067 Sort with Swap(0, i) (25 分) 题意 给定长度为 \(n\) 的排列,如果每次只能把某个数和第 \(0\) 个数交换,那么要使排列是升序的最少需要交换几次. ...

随机推荐

  1. OLAP(On-Line Analytical Processing)

    自20世纪80年代开始,许多企业利用关系型数据库来存储和管理业务数据,并建立相应的应用系统来支持日常的业务运作.这种应用以支持业务处理为主要目的,被称为联机事务处理(On line Transacti ...

  2. Python 打开文件(File Open)

    版权所有,未经许可,禁止转载 章节 Python 介绍 Python 开发环境搭建 Python 语法 Python 变量 Python 数值类型 Python 类型转换 Python 字符串(Str ...

  3. hdu 2578 Dating with girls(1) 满足条件x+y=k的x,y有几组

    Dating with girls(1) Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  4. PyCharm下创建并运行我们的第一个Django项目

    PyCharm下创建并运行我们的第一个Django项目 准备工作: 假设读者已经安装好python 2x或3x,以及安装好Django,以及Pycharm 1. 创建一个新的工程 第一次运行Pycha ...

  5. openstack trove实例状态转换条件--Mitaka版本

    今天研究了一下trove的instance状态转换条件.发现其实设计的挺复杂的.后来思考了一下这样设计的原因.我觉得大致是因为,如果instance的状态全部来自于instance上跑的数据库服务本身 ...

  6. storm on yarn(CDH5) 部署笔记

    按照storm on yarn(Apache hadoop)部署好之后,然后修改HADOOP_HOME,hadoopenv.sh中的JAVA_HOME,以及storm-yarn-master中pom. ...

  7. java web实现在线编辑word,并将word导出(三)

    前面说到前台呈现的页面是img标签,因此需要在后台生成相应的图片,在img的src内容中改为相应的路径地址:而在生成文档的过程中需要替换相应的img标签.后一部分上篇文章已经讲过,本片主要讲前一部分. ...

  8. statement 、prepareStatement的用法和解释

    转自:http://blog.csdn.net/QH_JAVA/article/details/48245945   一.prepareStatement 的用法和解释 1.PreparedState ...

  9. SublimeText3和插件的安装

    SublimeText3和插件的安装 步骤一:进入官网下载SublimeText3(http://www.sublimetext.com/3),安装并打开SublimeText3   步骤二:进入Su ...

  10. LeetCode刷题笔记(1-9)

    LeetCode1-9 本文更多是作为一个习题笔记,没有太多讲解 1.两数之和 题目请点击链接 ↑ 最先想到暴力解法,直接双循环,但是这样复杂度为n平方 public int[] twoSum(int ...