1055 集體照 (25 分)

題目:1055 集體照 (25 分)

拍集體照時隊形很重要,這裏對給定的 N 我的 K 排的隊形設計排隊規則以下:node

  • 每排人數爲 /(向下取整),多出來的人所有站在最後一排;ios

  • 後排全部人的個子都不比前排任何人矮;數組

  • 每排中最高者站中間(中間位置爲 /,其中 m 爲該排人數,除法向下取整);框架

  • 每排其餘人以中間人爲軸,按身高非增序,先右後左交替入隊站在中間人的兩側(例如5人身高爲190、18八、18六、17五、170,則隊形爲17五、18八、190、18六、170。這裏假設你面對拍照者,因此你的左邊是中間人的右邊);函數

  • 若多人身高相同,則按名字的字典序升序排列。這裏保證無重名。測試

現給定一組拍照人,請編寫程序輸出他們的隊形。spa

輸入格式:

每一個輸入包含 1 個測試用例。每一個測試用例第 1 行給出兩個正整數 N(≤,總人數)和 K(≤,總排數)。隨後 N 行,每行給出一我的的名字(不包含空格、長度不超過 8 個英文字母)和身高([30, 300] 區間內的整數)。設計

輸出格式:

輸出拍照的隊形。即K排人名,其間以空格分隔,行末不得有多餘空格。注意:假設你面對拍照者,後排的人輸出在上方,前排輸出在下方。code

輸入樣例:

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

思路:

  • 根據第二點條件能夠知道,就是在排隊前先將他們按身高從高到低排,同身高得按字母序。用排序加比較函數便可解決。
  • 每排中最高的人排在 m/2+1 的位置,按照第四點條件,又以完成按身高排序,那麼這就不須要特列,由於最高的人第一個被排,後面的人在他左右排,最後每排中這個最高的人天然而然地就站到了 m/2+1 的位置,這也算是一種規律吧。
  • 本體代碼的關鍵在於如何給每排排好隊。我排隊沒有用到輔助數組,而是直接將排好隊的隊伍拿來排,直接排在本身的位置,這樣就能夠直接輸出了(這樣的話,就須要找到排隊的規律),但也正是由於這樣,代碼就顯得有點冗長(主要是沒有改進的緣由)。
    排隊規律:
      1.按題目的排法,以每排最高的人排中間,剩下的左右分配,那麼最高的人的左邊身高是從矮到高的,而右邊是從高到矮站的。這點能夠利用。其次是左右排,那不就至關因而隔一我的排嗎。
         2.要是是平常生活,直接報2出列,排成兩排後拼接成一排就能夠了。代碼實現的話得判斷每排人數的奇偶(除了最後一排會有特殊狀況,其餘排的奇偶性是一致的,因此其實只用判斷一次),分奇偶的緣由:奇數我的的話,隔一人取人,最後一我的就是排右邊的;偶數則相反,最後一我的排左邊。
      3.舉個例子加以理解上述文字(純文字看着會枯燥,還容易繞):
        5人身高爲190、18八、18六、17五、170。按我說的排隊規律就是:先判斷奇偶,排成一排爲奇數個,那麼從倒數第二個取起,爲左邊第一我的,隔一個取,那麼排序的結果爲17五、188.排完後取第一我的(最高的)繼續後排順序就是190、18六、170.二者合在一塊兒就是一排排完序後的順序。1位175,二位188,三位190,四位186,五位(最後一位)170.

代碼:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cctype>
 4 #include <iostream>
 5 #include <sstream>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <string>
 9 #include <stack>
10 #include <queue>
11 #include <vector>
12 #include <map>
13 using namespace std; 14 
15 struct node{ 16     string s; 17     int h; 18 }per[10005]; 19 
20 bool cmp(node a, node b) 21 { 22     if(a.h == b.h) 23         return a.s < b.s; 24     else
25         return a.h > b.h; 26 } 27 
28 int main() 29 { 30     int n, k; 31     scanf("%d %d", &n, &k); 32     for(int i = 0; i < n; i++) 33  { 34         cin >> per[i].s >> per[i].h; 35  } 36     sort(per, per + n, cmp); 37     int m = n / k;    //各排的人數 
38     int fm = m + n % k;    //最後一排的人數 
39     for(int i = 0; i < k; i++) 40  { 41         if(i == 0 && n%k)  //如有人多出放最後一排特殊處理 42  { 43             for(int j = fm-1; j > 0; j-=2)    //輸出 左列 
44  { 45                 cout << per[j].s; 46                 printf(" "); 47  } 48             for(int j = 0; j < fm; j+=2)    //輸出 右列 
49  { 50                 cout << per[j].s; 51                 if(j != fm-2) 52                     printf(" "); 53  } 54             printf("\n"); 55  } 56         else
57  { 58             if(m % 2) //若是一排人數奇數個
59  { 60                 for(int j = fm+i*m-2; j > fm+(i-1)*m; j-=2)    //輸出 左列 
61  { 62                     cout << per[j].s; 63                     printf(" "); 64  } 65                 for(int j = fm+(i-1)*m; j < fm+i*m; j+=2)    //輸出 右列 
66  { 67                     if(j != fm+(i-1)*m) 68                         printf(" "); 69                     cout << per[j].s; 70  } 71                 printf("\n"); 72  } 73             else  //每排偶數個
74  { 75                 for(int j = fm+i*m-1; j > fm+(i-1)*m; j-=2)    //輸出 左列 
76  { 77                     cout << per[j].s; 78                     printf(" "); 79  } 80                 for(int j = fm+(i-1)*m; j < fm+i*m; j+=2)    //輸出 右列 
81  { 82                     if(j != fm+(i-1)*m) 83                         printf(" "); 84                     cout << per[j].s; 85  } 86                 printf("\n"); 87  } 88  } 89  } 90     return 0; 91 }

 

總結:

  • 每排人數沒分奇偶,只有測試點三、5過了。其餘基本顯示格式錯誤,沒分奇偶影響格式,就是空格了吧。確實如此。
  • 分奇偶後,測試點1答案錯誤,2格式錯誤。後來想多是所有排成一排和每排只有一我的的狀況出錯。將最後一排按有人多出時再特殊處理後就AC了。(也不是很清楚爲啥忽然就A了,等二刷)

  打代碼就像寫文章,不斷修改才能不斷加深功底,思路是框架,填充好細節才成文。真正的快樂來源於不斷的嘗試與失敗後終於迎來的成功。blog

相關文章
相關標籤/搜索