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\) 个数交换,那么要使排列是升序的最少需要交换几次. ...
随机推荐
- Hello 2019【A,B,C】
#include<bits/stdc++.h> using namespace std; #define int long long signed main(){ string str; ...
- CSS3 新增选择器:伪类选择器和属性选择器
一.结构(位置)伪类选择器( : ) 1.:first-child 2.:last-child 3.:nth-child(n)或者:nth-child(2n)或者:nth-child(2n+1) &l ...
- 利用fgetc合并2个源文件的内容,到一个新的文件中
#include <stdio.h> #include <stdlib.h> //功能: 合并2个源文件的内容,到一个新的文件中 int main(int a,char *ar ...
- hihoCoder #1143 : 骨牌覆盖问题·一(矩阵乘法)
1143 : 骨牌覆盖问题·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形棋盘,然 ...
- centos host-only网卡配置
1.更改网卡配置 更改虚拟机/etc/sysconfig/network-scripts/ifcfg-enp0s3 文件,内容如下: TYPE=Ethernet PROXY_METHOD=none B ...
- A. Vasya and Book ( Codeforces Educational Codeforces Round 55 )
题意:当前在看书的第 x 页,每次可以向前或者向后翻 d 页,这个书一共 n 页,问能否用最小操作翻到第 y 页. 题解:三种情况:1.直接翻能到的一定最短. 2.先翻到第一页,然后往后翻,翻到第 y ...
- datagrid其中某列需要动态隐藏或显示的mvvm绑定方式,也可以用在其他表格类型控件上
版权归原作者所有. 引用地址 [WPF] HOW TO BIND TO DATA WHEN THE DATACONTEXT IS NOT INHERITED MARCH 21, 2011 THOMAS ...
- LocalStorage 的 具体操作 与 设置有效期
读取与存储 的使用方法 //存储 (名称 , 内容 , 有效期<小时> ) // 如果想要自己改变 有效期的单位 可以在 set 方法中 // 找到 这两个 setHours getHou ...
- 【洛谷】P4167 [Violet]樱花
题面 又懒得弄题面,开个传送门吧 分析 人生第一次切数学题,我们先把方程写出来 $$\frac {1}{x}+\frac {1}{y}=\frac {1}{n!}$$ 现在我们知道的条件是x,y都是正 ...
- Ubuntu16.04Apache负载均衡+集群
mod_proxy ,主代理模块Apache模块用于重定向连接;它允许Apache充当底层应用程序服务器的网关.mod_proxy_http ,它增加了对代理HTTP连接的支持.mod_proxy_b ...