把原序列按 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; }