1. 程式人生 > 實用技巧 >[PAT] A1067 Sort with Swap(0, i)

[PAT] A1067 Sort with Swap(0, i)

思路

貪心策略。
(1)每次讓0佔的位置上本來應該佔的數字與0交換,交換結束後該數歸位。
(2)但有可能數字0在自己的位置上(即第0位),但仍有其他數字沒有歸位。則此時將0與其交換,讓它暫時佔據0位,重複步驟(1)。
優化:
在(2)中,如果每次都迴圈去找沒有歸位的數字,若那個數字在很後面,則要判斷很多次,測試點1、2會超時。因此最外層迴圈是i從數字0到數字n-1,每一次迴圈結束後,數字i的狀態可能有兩種,一種是在0不斷“讓位”中歸位(即它與0處在同一個錯位圈中);另一種是0不斷“讓位”也不能導致它歸位,則強制讓它暫時佔據0位,在下一次迴圈的時候,數字0要想回到0位,必須通過與它交換才可以(則在程式碼中的while迴圈內實現),而0與它交換的條件只能是因為0佔據了它本來的位置,則它必然能在下一次迴圈中歸位。

AC程式碼

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#define MAX 100000
int main() {
	int i, temp, times = 0, n, locate[MAX];
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		scanf("%d", &temp);
		locate[temp] = i;
	}
	for (i = 1; i < n; i++) {
		while (locate[0] != 0) {
			temp = locate[locate[0]];
			locate[locate[0]] = locate[0];
			locate[0] = temp;
			times++;
		}
		//如果每次判斷0歸位後,再尋找沒歸位的數字,就會多餘迴圈判斷,引起超時。
		if (locate[i] != i) {//此時代表數字0已歸位,但是數字i仍然不在自己的位置上
			//則需要交換0和i,也即數字0的位置和數字i的位置對調
			temp = locate[i];
			locate[i] = locate[0];
			locate[0] = temp;
			times++;
		}
	}
	printf("%d", times);
	return 0;
}