質問
1067 Swap(0, i) によるソート (25 分)
数値 {0, 1, 2,…, N−1} の順列が与えられた場合、それらを昇順にソートするのは簡単です。しかし、Swap(0, *) が使用を許可される唯一の操作である場合はどうなるでしょうか? たとえば、{4, 0, 2, 1, 3} を並べ替えるには、次の方法でスワップ操作を適用できます。
スワップ(0, 1) => {4, 1, 2, 0, 3}
スワップ(0, 3) => {4, 1, 2, 3, 0}
スワップ(0, 4) => {0, 1 , 2, 3, 4}
次に、最初の N 個の非負の整数の指定された順列をソートするために必要なスワップの最小数を見つけるように求められます。
入力仕様:
各入力ファイルには 1 つのテスト ケースが含まれており、正の N (≤ 10
5
) の後に {0, 1, …, N−1} の順列シーケンスが続きます。行内のすべての数値はスペースで区切られます。
出力仕様:
それぞれの場合において、指定された順列をソートするために必要なスワップの最小数を 1 行に出力するだけです。
入力例:
10
3 5 7 2 6 4 9 0 8 1
末尾に空白行なし
出力例:
9
一連の考え
配列を使用してデータを保存します。num[temp] は数値 temp の場所を示します。標準位置にない要素の数を記録し、それが 0 でない限り周期的に交換を続けます。
コード
#include<bits/stdc++.h>
using namespace std;
int num[100010];
int main(){
int n,temp,ans=0;
cin>>n;
int left=n-1;
for (int i = 0; i < n; ++i) {
cin>>temp;
num[temp] = i;
if(temp==i && i!=0)
--left;
}
int k = 1;
while (left>0){
if(num[0]==0){
//0在本位上,则与最小的不在本位上的元素交换
while(k<n){
if(num[k]!=k){
ans++;
swap(num[0],num[k]);
break;
}
k++;
}
}
while(num[0]!=0){
swap(num[0],num[num[0]]);
left--;
ans++;
}
}
cout<<ans;
return 0;
}
要約する
この質問ではベクトルを使用できません。配列の長さが 100,000 に達したため、vector を使用するとセグメンテーション違反が発生します。