計蒜客-題庫-三值排序
阿新 • • 發佈:2017-05-04
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; }
計蒜客-題庫-三值排序