PAT Advanced 1067 Sort with Swap(0,*) (25) [贪⼼算法]
题目
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与其他数字交换位置)
解题思路
- 贪心算法:如果当前数字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;"
定义数组int pos[N],记录数字所在位置(如:pos[i],表示数字i在pos[i]的位置) - 哨兵为数字0,pos[0]=0,不一定排序已完成
- pos[0]==0,但是排序未完成,将0需要与不在本位的数字交换(因为如果0与已回到本位的数字交换会导致交换次数变多),定义数字k初始化为1,记录当前不在本位的最小数字(避免每次都循环遍历数组,查找未回到本位的数字(复杂度为O(n^2)有两个点会超时))
- pos[0]==0,已完成排序(如何检测已完成排序?--定义变量left记录除0以外不在自己本位数字的个数,left=0表示排序完成)
注意点
- 当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) [贪⼼算法]的更多相关文章
- PAT甲题题解-1067. Sort with Swap(0,*) (25)-贪心算法
贪心算法 次数最少的方法,即:1.每次都将0与应该放置在0位置的数字交换即可.2.如果0处在自己位置上,那么随便与一个不处在自己位置上的数交换,重复上一步即可.拿样例举例: 0 1 2 3 4 5 ...
- 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 ...
- 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 ...
- 1067. Sort with Swap(0,*) (25)
时间限制 150 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Given any permutation of the num ...
- PAT (Advanced Level) 1067. Sort with Swap(0,*) (25)
只对没有归位的数进行交换. 分两种情况: 如果0在最前面,那么随便拿一个没有归位的数和0交换位置. 如果0不在最前面,那么必然可以归位一个数字,将那个数字归位. 这样模拟一下即可. #include& ...
- 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 ...
- pat1067. Sort with Swap(0,*) (25)
1067. Sort with Swap(0,*) (25) 时间限制 150 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue G ...
- 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 ...
- PTA 1067 Sort with Swap(0, i) (贪心)
题目链接:1067 Sort with Swap(0, i) (25 分) 题意 给定长度为 \(n\) 的排列,如果每次只能把某个数和第 \(0\) 个数交换,那么要使排列是升序的最少需要交换几次. ...
随机推荐
- 【转】美团 MySQL 数据实时同步到 Hive 的架构与实践
文章转载自公众号 美团技术团队 , 作者 萌萌 背景 在数据仓库建模中,未经任何加工处理的原始业务层数据,我们称之为ODS(Operational Data Store)数据.在互联网企业中,常见的 ...
- Docker每次启动容器,IP及hosts指定
原文链接:https://blog.csdn.net/u012834750/article/details/80508464 前言 每次在使用Docker启动Hadoop集群的时候,都需要重新绑定下网 ...
- Python安装和虚拟环境创建以及外部库的安装
Python.虚拟环境.外部库的安装 一 安装Python 1 Windows 到官网下载对应的版本 下载地址 我选择的是Python3.6.8 下载完成后双击运行 !!!勾选Add Python 3 ...
- Vue.js(2)- 过滤器
概念:过滤器本质上就是一个函数,可被用作一些常见的文本格式化. 过滤器只可以用在两个地方:mustache 插值表达式和 v-bind 表达式. 过滤器应该被添加在 JavaScript 表达式的尾部 ...
- 深入理解Canvas Scaler
Canvas Scaler: 这是一个理解起来相当繁琐复杂的一个组件,但又是一个至关重要的组件,不彻底了解它,可以说对UGUI的布局和所谓的“自适应”就没有一个完整的认识. Canvas Scale指 ...
- CCCC 正整数A+B
题意: 本题的目标很简单,就是求两个正整数A和B的和,其中A和B都在区间[1,1000].稍微有点麻烦的是,输入并不保证是两个正整数. 输入格式: 输入在一行给出A和B,其间以空格分开.问题是A和B不 ...
- CodeForces - 748D Santa Claus and a Palindrome (贪心+构造)
题意:给定k个长度为n的字符串,每个字符串有一个魅力值ai,在k个字符串中选取字符串组成回文串,使得组成的回文串魅力值最大. 分析: 1.若某字符串不是回文串a,但有与之对称的串b,将串a和串b所有的 ...
- POJ 1469:COURSES
COURSES Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19458 Accepted: 7658 Descript ...
- group_concat用法以及字符串太长显示不全
由于group_concat默认的长度是1024,所以要将最大长度修改 首先执行 SET SESSION group_concat_max_len = 10240;#一次查询有效 然后再进行拼接 se ...
- 一个简单的“将ball个球放到box各盒子中,每个盒子不多于m个,并且满足limit条件的状态”的函数
前段时间,做了一个某游戏的辅助计算工具,其中遇到一个排列组合问题.抽象出来就是 将ball个球放到box各盒子中,每个盒子不多于m个,并且满足limit条件, 请给出所有的这些状态. 随意找了下没有现 ...