我的PAT-BASIC代码仓
https://github.com/617076674/PAT-BASIC
我的PAT-ADVANCED代码仓
https://github.com/617076674/PAT-ADVANCED
原题链接
PAT-BASIC1055
https://pintia.cn/problem-sets/994805260223102976/problems/994805272021680128
PAT-ADVANCED1109
https://pintia.cn/problem-sets/994805342720868352/problems/994805360043343872
题目描述
PAT-BASIC1055
PAT-ADVANCED1109
知识点
排序
思路
(1)定义一个学生结构体,存放名字和身高。
(2)计算每行的学生人数,最后一行需要特殊处理。
(3)自定义学生结构体的比较函数,按题目给的排序规则对学生进行排序处理。
(4)按照行数,对学生进行分组,按题目规则打印每一行的学生名字,需要注意的是,最后一行反而是最先输出的。
(5)定义一个显示单行学生的函数。按题目所述,该函数先把最高的学生放在一行的中间位置,再用两个指针left和right标记将要放置的左边和右边的位置,按身高降序依次排列学生即可。
注意点
左右相反,题目说了一排中确定最高者位置后先右后左站在中间人的两侧,由于我们面对着拍照者,在代码实现中应该是先左后右站在中间人的两侧。
复杂度分析
时间复杂度是O(NlogN)。空间复杂度是O(N)。
C++代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
struct person{ //存储人名和身高
char name[9];
int height;
};
bool cmp(person p1, person p2); //按升高降序排序,若身高相同,则按人名升序排序
void showPeople(vector<person> row); //显示每一行的人名
int main(){
int N, K;
scanf("%d %d", &N, &K); //读取总人数和总行数
person people[N];
for(int i = 0; i < N; i++){
scanf("%s %d", people[i].name, &people[i].height); //读入每个人的人名和身高
}
sort(people, people + N, cmp); //按身高从高到低排序
int otherRow = N / K; //除最后一行的每行人数
int lastRow = N - otherRow * (K - 1); //最后一行的人数
vector<person> row; //存储每行的人
for(int i = N - 1; i >= N - lastRow; i--){
row.push_back(people[i]); //最后一行
}
showPeople(row); //先输出最后一行的人名
for(int i = 0; i < K - 1; i++){
row.clear(); //开始新的一行前先清空row
for(int j = N - lastRow - 1 - otherRow * i; j >= N - lastRow - otherRow * (i + 1); j--){ //按每行otherRow个人对people数组中的数据进行分行
row.push_back(people[j]); //其他行
}
showPeople(row); //输出其他行的人名
}
return 0;
}
bool cmp(person p1, person p2){
if(p1.height == p2.height){
return strcmp(p1.name, p2.name) > 0;
}else{
return p1.height < p2.height;
}
}
void showPeople(vector<person> row){
int size = row.size();
person people[size];
int mid = size / 2; //确定最高者的位置,索引从0开始
people[mid] = row[0];
int left = mid - 1; //确定最高者左边的下一个位置
int right = mid + 1; //确定最高者右边的下一个位置
for(int i = 1; i < size; i++){
if(i % 2 == 1){ //先放左边
people[left--] = row[i];
}else{ //再放右边
people[right++] = row[i];
}
}
for(int i = 0; i < size; i++){ //输出每行人名
printf("%s", people[i].name);
if(i != size - 1){
printf(" ");
}else{
printf("\n");
}
}
}
C++解题报告