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