1.タイトルの説明
入力仕様:
出力仕様:
いずれの場合も、特定の順列をソートするために必要な最小数のスワップを1行に出力するだけです。
入力例:
10
3 5 7 2 6 4 9 0 8 1
出力例:
9
2、問題解決のアイデア
タイトル通り、0などの数字の位置を常に変えてソートを行わなければなりません。タイトルが伝えられたように、入力された数字は{0、1、...、N − 1} \ {0,1、...、N-1 \}です{ 0 、1 、。。。、N−1 }このシーケンスバリアントは、ここで説明する並べ替えが実際に各番号を配列の対応する添え字に格納することであることを理解するのは難しくありません。配列posを使用して、各数値に対応する位置を表すことができます。0の位置が0でない場合は、常に最初の数値を0に交換します。同時に、count ++は、0が最初の位置に転送されている場合、正しい位置に「立っていない」数値があるかどうかを確認します。ある場合は、それらを一度交換してループに戻り、すべてが正しい位置にある場合は、カウントを出力します。
3、ACコード
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
scanf("%d", &n);
vector<int> pos(n);
for (int i=0; i<n; i++) //初始化pos数组,表示每个数字对应的位置
{
int temp;
scanf("%d", &temp);
pos[temp] = i;
}
int count = 0; //进行了几次交换
int checkPos = 1; //已经就位的数字个数
bool sorted = false; //标记是否已经排序完成
while (!sorted) //swap(0, i)
{
if (pos[0] != 0)
{
int i = pos[0]; //暂存0的位置
pos[0] = pos[i]; //将0交换过去
pos[i] = i; //将i移到一开始0的位置
count++;
continue;
}
//检查是否仍存在错位
while (checkPos<n && pos[checkPos]==checkPos) checkPos++;
if (checkPos==n) sorted = true; //n个元素全都在正确的位置
else //否则要用0再去和不在正确位置的数字交换
{
//swap(0, i)
pos[0] = pos[checkPos];
pos[checkPos] = 0;
count++;
}
}
printf("%d\n", count);
return 0;
}