把原序列按 non-decreasing排序,而後把排序後的數組和原序列一一比較,找出本該排1的位置放了2的、3的,本該放2的位置放了1的、3的……ios
因爲一次exchange能夠把1和2對換,1和3對換,2和3對換,因此作這些交換,而後剩下的就是三個都不一樣的了,這樣每一組都至少通過兩次交換才能恢復(好比312經兩次交換才能夠變成123)。看代碼更清楚,很簡單的思路,很簡短的代碼。數組
/* ID: LANG: C++ TASK: sort3 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int toChange[4][4]; //toChange[i][j]:本該排i的位置排了j int N; int num[1005]; //原數組 int sorted[1005]; //排序後的數組 int change; //交換次數 int main() { freopen("sort3.in", "rb", stdin); freopen("sort3.out", "wb", stdout); cin >> N; for(int i = 0; i < N; i++) { cin >> num[i]; sorted[i] = num[i]; } sort(sorted, sorted + N); memset(toChange, 0, sizeof(int)); for(int i = 0; i < N; i++) { if(sorted[i] == 1 && num[i] == 2) toChange[1][2]++; else if(sorted[i] == 1 && num[i] == 3) toChange[1][3]++; else if(sorted[i] == 2 && num[i] == 1) toChange[2][1]++; else if(sorted[i] == 2 && num[i] == 3) toChange[2][3]++; else if(sorted[i] == 3 && num[i] == 1) toChange[3][1]++; else if(sorted[i] == 3 && num[i] == 2) toChange[3][2]++; } change = 0; int leave = 0; //leave:兩兩交換以後剩下的 for(int i = 1; i <= 2; i++) { for(int j = 1; j <= 3 - i; j++) { int minn = min(toChange[i][i+j], toChange[i+j][i]); change += minn; toChange[i][j+i] -= minn; toChange[j+i][i] -= minn; leave = leave + toChange[i][j+i] + toChange[j+i][i]; } } change += leave * 2 / 3; cout << change << endl; fclose(stdin); fclose(stdout); return 0; }