PAT 甲级 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 分)(贪心,思维题)*的更多相关文章
- 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 ...
- 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 ...
- 【PAT甲级】1067 Sort with Swap(0, i) (25 分)
题意: 输入一个正整数N(<=100000),接着输入N个正整数(0~N-1的排列).每次操作可以将0和另一个数的位置进行交换,输出最少操作次数使得排列为升序. AAAAAccepted cod ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- A1067 Sort with Swap(0, i) (25 分)
一.技术总结 题目要求是,只能使用0,进行交换位置,然后达到按序排列,所使用的最少交换次数 输入时,用数组记录好每个数字所在的位置. 然后使用for循环,查看i当前位置是否为该数字,核心是等待0回到自 ...
- PTA 1067 Sort with Swap(0, i) (贪心)
题目链接:1067 Sort with Swap(0, i) (25 分) 题意 给定长度为 \(n\) 的排列,如果每次只能把某个数和第 \(0\) 个数交换,那么要使排列是升序的最少需要交换几次. ...
随机推荐
- 华硕ASUS U5800GE驱动
重要的触摸板 微软商店 ASUS Keyboard Hotkeys 设备管理器 人体学输入设备 ASUS Precision Touchpad (ScreenPad) Asus ScreenPad D ...
- 学习Spring-Data-Jpa(二)---JPA基本注解
基本注解 1.@Entity :用于添加在实体类上,定义该JAVA类成为被JPA管理的实体,将映射到指定的数据库表.如定义一个实体类Category,它将映射到数据库中的category表中. 2.@ ...
- Java基础学习【字符串倒序输出+排序】
字符串逆序输出 import java.util.*; public class Main{ public static void main(String [] args) { //字符串逆序输出 S ...
- codevs1580单词游戏
题目描述中说: 单词为at,k=8则新单词为ib 推移规则是:如果k为正数则下推,否则上推,当推移超越边界时回到另一端继续推移. 但在我做题时发现: 这个描述与数据所要求的是完全相反的!!!! 样例1 ...
- 深入剖析mmu地址转化
mmu(内存管理单元),是arm区别于单片机的标志之一,虚拟地址转化分为3种,常见的如下2种. 段式转化如下,由表像中的基地址加偏移地址,(细页转化跟段式转化类似,多了一个2级页表,把虚拟地址0-20 ...
- Firefox设置谷粉搜搜为默认搜索引擎的方法
原文转自:http://www.gfsoso.org/119/ 作者: cjx 分类: 谷粉专题 发布时间: 2014-07-09 23:10 ė 668条评论 如果使用Firefox的朋友希 ...
- JSP带有标签体的自定义标签
新建OutTag类 如何添加jsp-api.jar包 OutTag类详细代码 ``` package bid.zhazhapan.fims.tag; import javax.servlet.jsp. ...
- CTYZ的树论赛(P5557 旅行/P5558 心上秋/P5559 失昼城的守星使)
总结 由于受中秋节影响,没能在比赛时间内切掉\(T3\) 思维难度\(T1<T2<T3\),代码难度\(T1>T2>T3\) P5557 旅行 显然跳到环上去后就可以直接模了, ...
- [内网渗透]IPC$共享连接
0x01 简介 IPC$(Internet Process Connection)是共享"命名管道"的资源,它是为了让进程间通信而开放的命名管道,可以通过验证用户名和密码获得相应的 ...
- 10个超漂亮的CSS 3D特效
10个超漂亮的CSS 3D特效 一.总结 一句话总结: 后面有空得好好练一练,也可以作为录课素材 二.10个超漂亮的CSS 3D特效 转自或参考:10个超漂亮的CSS 3D特效https://blog ...