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. GITHUB使用指南、

    一.安装Git1.通过官网(https://www.git-scm.com/download/)下载git,进入官网,如下图所示:2.选择对应的操作系统后,页面跳转并自动下载对应的Git版本,如下图所 ...

  2. Kubernetes 学习18配置网络插件flannel

    一.概述 1.我们在学习docker时知道docker有四种常用的网络模型 a.bridge:桥接式网络 b.joined:联盟式网络,共享使用另外一个容器的网络名称空间 b.opened:容器直接共 ...

  3. b/s实现大文件上传分片上传断点续传

    关键部分 前端用file.slice()分块 前端用FileReader获取每一分块的md5值 后端用MultipartFile接受分块文件 后端用FileOutputStream拼装分块文件 话不多 ...

  4. 浏览器URL中“#” “?” &“”作用

    1. # 10年9月,twitter改版.一个显著变化,就是URL加入了"#!"符号.比如,改版前的用户主页网址为http://twitter.com/username改版后,就变 ...

  5. C函数指针数组的定义和使用

    1.使用函数指针数组来实现计算器 2.通过函数指针变量来调用对应的函数 #include <stdio.h> int add(int a,int b){ return a+b; } int ...

  6. lixuxmint系统定制与配置(3)-字体

    小书匠Linux 有些系统自带的字体实在太难看了,看起来不清晰,不明确,有一个好的字体,可以带来好心情,并提高工作与效率. 1.常用中文字体 文泉驿微黑,微软雅黑,思源黑体 2.字体安装 2.1检查已 ...

  7. 机器学习实战(1)- KNN

    KNN:k近邻算法-在训练样本中找到与待测样本距离相近的N个样本,并用这N个样本中所属概率最大的类别作为待测样本的类别. 算法步骤: 1.对训练中的样本数据的不同属性进行归一化处理. 2.计算待测样本 ...

  8. java学习笔记(2)注释、public lcass、class、标识符、字面值、变量

    java学习笔记(1)中说过了java的一些基础知识,发展史,特点,编译和运行过程,配置环境变量等,接下来开始介绍java的语法等只是点  关于java源程序中的注释: *什么是注释?注释的作用是什么 ...

  9. nodejs新工具-cypress和testcofe的崛起

    今天咨询一个自动化 工具问题,偶然间有人提起了这个可能以后会很火的工具,在此找到一篇很好的参考文章 记录并为以后做准备 cypress和testcofe https://www.jianshu.com ...

  10. NOIP(划掉)CSP2019一轮知识点

    今年似乎变动很大呢…… 去年总结的 历年真题 以下标题中打*的是我认为的重点内容 *一.关于计算机 (一)计算机组成 计算机的工作原理跟人的大脑很相似,而且还是大脑功能的延伸,所以习惯上叫它电脑. 硬 ...