1. 程式人生 > >計蒜客-題庫-三值排序

計蒜客-題庫-三值排序

pac 一個數 順序 col 裏的 efault 開始 algo div

題目

排序是一種很頻繁的計算任務。一個實際的例子是,當我們給某項競賽的優勝者按金銀銅牌排序的時候。在這個任務中可能的值只有三種1,2和3。我們用交換的方法把他排成升序的。

寫一個程序計算出,計算出的一個包括1、2、3三種值的數字序列,排成升序所需的最少交換次數。

輸入第1行為類別的數量N(1≤N≤1000)

輸入第2行到第N+1行,每行包括一個數字(1或2或3)。

輸出包含一行,為排成升序所需的最少交換次數。

樣例輸入

9
2
2
1
3
3
3
2
3
1

樣例輸出

4

思路

對於排好序的1、2、3序列,看成一段1、一段2、一段3。對於每一段而言,數字是沒有順序之別的。那麽再看做是編號分別為1、2、3的盒子。而盒子裏的數字看做編號為1、2、3的球。一開始這些球無規則的放在3個盒子裏,現在做的就是把球放在相應盒子裏。分兩步:1、把2、3盒子裏的球重新放置,即2號盒子裏的y個3號球給3號盒子,3號盒子裏的z個2號球給2號盒子。交換次數為y、z的最大值。2、把1號盒子裏的2號球和3號球(共x個)分別與2、3盒子裏的1號球交換。

一共:x+max(y,z)

代碼

#include<iostream>
#include<algorithm>
using namespace std;
int n;
int s[1000];
int t[1000];
int x = 0, y = 0, z = 0;
void solve(){
    sort(t, t + n);
    for (int i = 0; i < n; ++i){
        if (s[i] != t[i]){
            switch (t[i]){
            case 1:
                x
++; break; case 2: if (s[i] == 3){ y++; } break; case 3: if (s[i] == 2){ z++; } break; } } } } int main(){ cin
>> n; for (int i = 0; i < n; ++i){ cin >> s[i]; t[i] = s[i]; } solve(); int num = x + (y>z ? y : z); cout << num << endl; return 0; }

計蒜客-題庫-三值排序