1067 Sort with Swap(0, i) (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 (≤) 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

题意:

给出{0, 1, ..., N−1} 的一个序列,要求通过两两交换的方式将其变为递增序列,但是每一次减缓必须用 0 与其它数进行交换。求最小交换次序。其中, N (≤10^​5​​)。

题解:

贪心算法:要求一个问题的最优解,先求局部最优解,即就是中间每一步都要是最优解

本题中,如果当前 0 处于 i 号位,则找到数字 i 当前所处的位置,然后把 0 与 i 进行交换,此时数字i 就位于它的最终位置上,取得了最优解。

对于本题很容易想到一个策略:如果当前 0 处于 i 号位,则找到数字 i 当前所处的位置,然后把 0 与 i 进行交换。但是思路存在一个问题:当0处于 0 号位时,将无法继续。因此,处理这个问题,当 0 回到 0 号位时,随意选择一个还没有回到本位的数字与 0 交换,从而继续。

思考:

容易想得到直接模拟交换过程,交换的时候cnt++,但是直接交换就算用了map还是测试1和测试2超时,无奈想不出好的方法,但是想到了,可以一开始数有多少个数字不在本本位上,答案按为个数-1,但是要加上有多少次0在交换过程中会被换到0本位,因为还要再换回去。但是具体不会操作,查了网上的题解,看到一个不错的写法,很简洁,方法是我一开始的模拟,但是它只开了一个数组,这个我没有想到。

比如:4 0 2 1 3

a[4]=0

a[0]=1  ** => a[0]=3

a[2]=2                        =>  4 1 2 0 3

a[1]=3  ** => a[1]=1

a[3]=4

交换0和1的位置,就算交换a[0]和a[a[0]]

下面对源代码做一点理解分析。外层for循环保证访问到每个元素,内层while(i!=a[i])保证本次访问操作中a[i]元素交换到它最终的位置上,在本次操作中也有可能会顺带将其他元素也交换到它对应的最终位置。访问操作的代码理解,0作为哨兵,首先将0所占的位置最终应该存的元素换回该位置,(a[0]表示0当前所在的位置)(这个操作即为有效操作),这样交换完毕后0会回到0对应的最终位置(即0),此时挑选任一个乱序元素暂存0位置,(这个操作即为无效操作),本算法选择0元素后面第一个乱序元素。
————————————————
版权声明:本文为CSDN博主「virgilshi」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/whutshiliu/article/details/82952258

AC代码:

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
int a[];
int n;
int cnt=;
int main(){
cin>>n;
for(int i=;i<n;i++){
int x;
cin>>x;
a[x]=i;
}
for(int i=;i<n;i++){
if(i!=a[i]){
while(a[]!=){
//0所在的位置 和 0所在位置(本位数)所在位置
swap(a[],a[a[]]);
cnt++;
}
if(i!=a[i]){
swap(a[],a[i]);
cnt++;
}
}
}
cout<<cnt;
return ;
}

超时代码:

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
map<int,int>val;//val[x]=y表示第i位置的值为y
map<int,int>add;//add[x]=y数字y在第i的位置
int n;
int con;
int main(){
cin>>n;
con=;
for(int i=;i<n;i++){
cin>>val[i];
add[val[i]]=i;//数字a[i]在第i的位置
}
int f=-;
while(){
if(val[]==){
f=-;
for(int i=;i<n;i++){
if(val[i]!=i){//存在第i个位置不是i
f=i;
break;
}
}
if(f==-)break;
con++;
val[]=val[f];
add[val[f]]=;
val[f]=;
add[]=f;
}else{
con++;
int x=add[];
val[add[x]]=;
add[]=add[x];
val[x]=x;
add[x]=x;
}
}
cout<<con;
return ;
}

PAT 甲级 1067 Sort with Swap(0, i) (25 分)(贪心,思维题)*的更多相关文章

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

    Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order ...

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

    Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order ...

  3. 【PAT甲级】1067 Sort with Swap(0, i) (25 分)

    题意: 输入一个正整数N(<=100000),接着输入N个正整数(0~N-1的排列).每次操作可以将0和另一个数的位置进行交换,输出最少操作次数使得排列为升序. AAAAAccepted cod ...

  4. PTA 10-排序6 Sort with Swap(0, i) (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/678 5-16 Sort with Swap(0, i)   (25分) Given a ...

  5. PAT甲级——A1067 Sort with Swap(0, i)

    Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order ...

  6. 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 orde ...

  7. 10-排序6 Sort with Swap(0, i) (25 分)

    Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order ...

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

    一.技术总结 题目要求是,只能使用0,进行交换位置,然后达到按序排列,所使用的最少交换次数 输入时,用数组记录好每个数字所在的位置. 然后使用for循环,查看i当前位置是否为该数字,核心是等待0回到自 ...

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

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

随机推荐

  1. IntelliJ IDEA:给 web 应用提供 JSTL 支持

    最近在看<Head First Servlet JSP>学习JSP,看到JSTL一章,为了添加JSTL支持折腾了好久. 网上的教程五花八门,而且多数比较旧. 我尝试了各种方法都没有成功,很 ...

  2. 有关 Java (jackson包问题 ,MappingJacksonHttpMessageConverter 和 MappingJackson2HttpMessageConverter问题)

    今天这一系列问题吃掉我四个小时,所以现在吸收掉. 一. 整理所有错误信息: 1.错误信息:java.lang.NoClassDefFoundError: Could not initialize cl ...

  3. Mysql 根据时间取出每组数据中最新的一条

    下策——查询出结果后将时间排序后取第一条 select * from a where create_time<="2017-03-29 19:30:36"order by c ...

  4. Linux rpm安装指定安装路径

    可以使用prefix参数. rpm -i –prefix=/home/gpadmin    greenplum-db-6.0.0-rhel6-x86_64.rpm 将greenplum-db-6.0. ...

  5. AGC 030 B - Tree Burning 结论+枚举

    考试 T2,是一个脑筋急转弯. 最暴力的贪心是每次先选左,再选右,再选左..... 然而这么做在一些情况下是错的. 但是,我们发现我们的选法一定是 $LLLLRLRLRLRLR$ 或 $RRRRLRL ...

  6. 10分钟用Python告诉你两个机器人聊天能聊出什么火花

    欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可! 现在不是讲各种各样的人工智能嘛,AI下棋,AI客服,AI玩家--其实我一直很好奇,两个AI碰上会怎样,比如一起下棋,一起打游戏-- 今天做个 ...

  7. [golang]A modern, fast and scalable websocket framework with elegant API written in Go

    A modern, fast and scalable websocket framework with elegant API written in Go http://bit.ly/neffos- ...

  8. P5025 [SNOI2017]炸弹

    原题链接  https://www.luogu.org/problem/P5025 闲话时刻: 第一道 AC 的黑题,虽然众人皆说水... 其实思路不是很难,代码也不是很难打,是一些我们已经学过的东西 ...

  9. php unset

    说明:unset ( mixed $var [, mixed $... ] ) : void unset() 销毁指定的变量. unset() 在函数中的行为会依赖于想要销毁的变量的类型而有所不同. ...

  10. 模板 - 图论 - 强连通分量 - Kosaraju算法

    这个算法是自己实现的Kosaraju算法,附带一个缩点,其实缩点这个跟Kosaraju算法没有什么关系,应该其他的强连通分量算法计算出每个点所属的强连通分量之后也可以这样缩点. 算法复杂度: Kosa ...