usaco: Sorting a Three-Valued Sequence

把原序列按 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;
}
相關文章
相關標籤/搜索