对于一个由0到N-1的序列,如果只能交换0和另一个数的位置,求多少次能够将序列变为递增序列。
输入为<N> <序列>(N和序列之间有一个空格,序列元素之间均有一个空格)。
设序列存储在数组A里。
一个直接的思路是将0和0所在位置应有的元素交换,如果0到达了0号位置但是序列没有完全变成递增序列,则让0和一个没有归位的元素进行一个废交换,然后再进行后续的交换。
一个独特的思路是,将0应在位置的元素(即A[0])换到它应该在的位置(例如A[0]=3,则把A[0]和A[3]交换),不断这样交换,直到0真正到了0位置,判断一下是否全部归位,不然的话就把0换到第一个没有归位的元素上,其实这一步就是上面的废交换,接下来再重复进行上面的交换,直到序列变为递增序列。要注意的是,每次检索第一个没有归位的元素时,起步的值根据A[0]所交换的位置开始,否则会超时。下面的算法用这个思路实现。
#include <iostream>
using namespace std; int FirstNotRight(int* A, int begin, int end){
for (int i = begin; i <= end; i++){
if (*(A + i) != i)
return i;
}
return 0;
} void Swap(int* a, int *b){
int temp = *a;
*a = *b;
*b = temp;
} int main(){
int N;
int input;
cin >> N;
int* A = (int*)malloc((N + 1)*sizeof(int));
for (int i = 0; i < N; i++){
scanf("%d", &input);
*(A + i) = input;
} int cur = FirstNotRight(A, 1, N - 1);
int count = 0;
while (cur != 0){ if (*A == 0){
Swap(A, A + cur);
count++;
} while (*A != 0){
int curtoswap = *A;
Swap(A, A + curtoswap);
count++;
} cur = FirstNotRight(A, cur, N - 1); }
cout << count << endl;
return 0;
}