1055 集体照 (25 分)

2019-10-18 14:57:33 浏览数 (1)

1055 集体照 (25 分)

拍集体照时队形很重要,这里对给定的 N 个人 K 排的队形设计排队规则如下:

  • 每排人数为 N/K(向下取整),多出来的人全部站在最后一排;
  • 后排所有人的个子都不比前排任何人矮;
  • 每排中最高者站中间(中间位置为 m/2 1,其中 m 为该排人数,除法向下取整);
  • 每排其他人以中间人为轴,按身高非增序,先右后左交替入队站在中间人的两侧(例如5人身高为190、188、186、175、170,则队形为175、188、190、186、170。这里假设你面对拍照者,所以你的左边是中间人的右边);
  • 若多人身高相同,则按名字的字典序升序排列。这里保证无重名。

现给定一组拍照人,请编写程序输出他们的队形。

输入格式:

每个输入包含 1 个测试用例。每个测试用例第 1 行给出两个正整数 N(≤104,总人数)和 K(≤10,总排数)。随后 N 行,每行给出一个人的名字(不包含空格、长度不超过 8 个英文字母)和身高([30, 300] 区间内的整数)。

输出格式:

输出拍照的队形。即K排人名,其间以空格分隔,行末不得有多余空格。注意:假设你面对拍照者,后排的人输出在上方,前排输出在下方。

输入样例:

代码语言:javascript复制
10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159

输出样例:

代码语言:javascript复制
Bob Tom Joe Nick
Ann Mike Eva
Tim Amy John

【我的代码】

代码语言:javascript复制
 1 // 1055 集体照 (25 分).cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
 2 //
 3
 4 #include <iostream>
 5 #include <vector>
 6 #include <algorithm>
 7 using namespace std;
 8 struct people
 9 {
10    string name;
11    int tall;
12 };
13 bool cmp(people p1, people p2) {
14    if(p1.tall != p2.tall)
15        return p1.tall > p2.tall;
16    return p1.name < p2.name;
17 }
18 int main()
19 {
20    //输入
21    int N, K;
22    vector<people> a;
23    cin >> N >> K;
24    int i = 0;
25    people peo;
26    for (; i < N; i  ) {
27        cin >> peo.name >> peo.tall;
28        a.push_back(peo);
29    }
30    //排序
31    sort(a.begin(), a.end(), cmp);
32    int line = N / K;
33    int remind = N % K;
34    vector<int> res_line;
35    for (i = 0; i < K; i  ) {
36        //把每行的数量行放入res_line中
37        if (i == 0) {
38            int tmp = remind   line;
39            res_line.push_back(tmp);
40        }
41        else {
42            res_line.push_back(line);
43        }
44    }
45    int index = 0;//来访问a向量
46    for (i = 0; i < res_line.size(); i  ) {
47        int tmp = res_line.at(i);//at可以检测是否越界
48        string b[tmp];
49        int count = 0;//已填人数
50        int media = tmp / 2;//中间位置
51        b[media] = a[index  ].name;
52        count  ;
53        while (count < tmp) {
54            //中间位置以左的元素
55            if (count % 2) {
56                b[media - count / 2 - 1] = a[index  ].name;
57                count  ;
58            }
59            //中间位置以右的元素
60            else {
61                b[media   count / 2] = a[index  ].name;
62                count  ;
63            }
64        }
65        cout << b[0];
66        for (int j = 1; j < tmp; j  ) {
67            cout << " " << b[j];
68        }
69        cout << endl;
70    }
71 }

【思路】

  1. 由于输入是成对的,身高与姓名一一对应,因此需要使用结构体来绑定这两个变量。 struct people { string name; int tall; };
  2. 根据题目要求,身高需要从大到小进行排列,并且当身高相同的时候,按名字的字典序升序排列,因此定义的比较函数如下: bool cmp(people p1, people p2) { if(p1.tall != p2.tall) return p1.tall > p2.tall; return p1.name < p2.name; }
  3. 然后就是很常规的输入模块和排序模块。
  4. 排完序后,需要确定每一行排多少人数,多出来的人(N % K)排在第一排即可。然后从中间位置开始,左边右边分别填好即可。

0 人点赞