題目來源html
拍集體照時隊形很重要,這裏對給定的 N 我的 K 排的隊形設計排隊規則以下:ios
每排人數爲 /(向下取整),多出來的人所有站在最後一排;數組
後排全部人的個子都不比前排任何人矮;測試
每排中最高者站中間(中間位置爲 /,其中 m 爲該排人數,除法向下取整);spa
每排其餘人以中間人爲軸,按身高非增序,先右後左交替入隊站在中間人的兩側(例如5人身高爲190、18八、18六、17五、170,則隊形爲17五、18八、190、18六、170。這裏假設你面對拍照者,因此你的左邊是中間人的右邊);設計
若多人身高相同,則按名字的字典序升序排列。這裏保證無重名。code
現給定一組拍照人,請編寫程序輸出他們的隊形。htm
每一個輸入包含 1 個測試用例。每一個測試用例第 1 行給出兩個正整數 N(≤,總人數)和 K(≤,總排數)。隨後 N 行,每行給出一我的的名字(不包含空格、長度不超過 8 個英文字母)和身高([30, 300] 區間內的整數)。blog
輸出拍照的隊形。即K排人名,其間以空格分隔,行末不得有多餘空格。注意:假設你面對拍照者,後排的人輸出在上方,前排輸出在下方。排序
10 3 Tom 188 Mike 170 Eva 168 Tim 160 Joe 190 Ann 168 Bob 175 Nick 186 Amy 160 John 159
Bob Tom Joe Nick Ann Mike Eva Tim Amy John
第三排:Bob Tom Joe Nick 第二排:Ann Mike Eva 第一排:Tim Amy John
單獨看第三排的人的身高
Bob Tom Joe Nick
175 188 190 186
假定最開始他們是有序的
即:190 188 186 175
題目要求的是,最高的在中間,按身高非增序,先右後左交替入隊站在中間人的兩側(這裏的左右,是相對於中間人的左右,即。咱們面對着中間人,對咱們來講就是先左後右)
什麼意思呢?
首先,咱們先把最高的放中間,190
接着,先左後右的入隊,下一個 188,變成 188 190
而後,186 入隊, 變成 188 190 186
以此類推能夠獲得:175 188 190 186
稍微分析一下能夠發現這個身高排名規律:
175 188 190 186
no4 no2 no1 no3
(就相似領獎臺的那種,冠亞季軍站旁邊)
假定條件:
t - 用來記錄當前一排的最大值的下標,初始化爲0
m - 當前一排的人數
res - 存放當前一排的人的名字
peoples - 全部人的名字、身高(已排序,高到低)
1. 首先:
res[m/2] = 身高最高的; // res[m/2] = 190
2. 遍歷 188 186 175,將 188 和 175 放在 190 的左邊
int j = 0; for (int i = t + 1; i < m + t; i += 2) { res[j++] = peoples[i].name; }
i += 2 就是隔一個取一個
m + t 就能夠理解爲是一個範圍,每次循環,輸出peoples數組 [ t, m + t)的內容(看後面解析)
i = t + 1 此時 t = 0,即從 peoples[1]開始,隔一個取一個(peoples[0]已經放到了中間)
第一行是 m = 4, t = 0, 那麼這一排的人在peoples中的下標就是 [ 0 , 3)
res 數組變成了 188 175 190
3. 這時候發現,咱們要的是 175 188 190,怎麼辦呢?reverse翻轉
reverse(res.begin(), res.begin() + j);
4. 接着咱們來處理 190 的右邊,和第二步是同樣的作法,須要注意的是,執行完第二部以後,另 j += 1 ,由於此時 j == m/2
for (int i = t + 2; i < m + t; i += 2) { res[j++] = peoples[i].name; }
這種狀況就不用 reverse 了,由於是按高到低的順序放到右邊的
5. 輸出當前一排(沒啥好說的了,注意格式
6. 更新 row 和 t 的值
row--;
t = m + t
理解一下 t = m + t
怎麼理解 t = m + t
#include <iostream> #include <string> #include<algorithm> #include <stack> #include <queue> #include <unordered_map> #include <iomanip> using namespace std; /* 190、18八、18六、17五、170 -> 17五、18八、190、18六、170 -> no四、no二、no一、no三、no5
*/ typedef struct Person { string name; int height; }Person; bool cmp(Person a, Person b) { if (a.height != b.height) { return a.height > b.height; } else { return a.name < b.name; } } int main() { int K; // 總排數 int N; // 總人數 cin >> N >> K; vector<Person> peoples(N); for (int i = 0; i < N; ++i) { cin >> peoples[i].name >> peoples[i].height; } sort(peoples.begin(), peoples.end(), cmp); int t = 0; int row = K; // 當前是第幾排 int m = 0; // 當前一排的人數 while (row) { if (row == K) { m = N - (K - 1)* N / K; // N÷K是每排的人數 } else { m = N / K; } // 數組都排好序了 // 190, 188, 186, 175, 170, 168, 168, 160, 160, 159 // N = 10, K = 3 // row = 3 // m = N - (K - 1)* N / K // = 10 - (3 - 1) * 10 / 3 // = 10 - 2 * 3 // = 4 最後一排有4我的 vector<string> res(m); //保存目前一排的人的名字 // t = 0, peoples[0]是最大的190,把它放到中間,也就是m/2 res[m / 2] = peoples[t].name; // 接着把188,175放到res[m/2]的左邊(保持順序175 188 res[m/2]),即:隔一個就取一個放到左邊 int j = 0; for (int i = t + 1; i < m + t; i += 2) { res[j++] = peoples[i].name; } reverse(res.begin(), res.begin() + j); // 把186,放到res[m/2]的右邊(保持順序),即:隔一個就取一個放到右邊 j += 1; for (int i = t + 2; i < m + t; i += 2) { res[j++] = peoples[i].name; } // 輸出 cout << res[0]; for (int i = 1; i < m; ++i) { cout << ' ' << res[i]; } cout << endl; t = t + m; row--; } return 0; }