题目
思路
1. 关于如何输出错位
当数组按身高降序排好后,可以发现以下规律:
原数组身高序为a【0】最高后降序排列
当m=5:输出顺序为【3】、【1】、【0】、【2】、【4】
当m=6:输出顺序为【5】、【3】、【1】、【0】、【2】、【4】
当m=7:输出顺序为【5】、【3】、【1】、【0】、【2】、【4】、【6】
可以发现规律为:
中间为0,左侧为奇数位、右侧为偶数位。
当m为偶数,第一位输出m-1
当m为奇数,第一位输出m-2
参考IamOliverLew的思路,可以将规律总结为:
左侧输出第一位为m/2*2 -1;
之后i-=2直至0,又从0开始i+=2输出偶数位。
2. 如何每行进行输出
通过创建函数,进行输出。函数返回值为结构体指针,s+num。使输出后的数舍弃,确保了每次输出的s[0]均为最大值。
3. 后三个测试点错误的问题
推测是后三个测试点有相同身高,不同姓名的数据。需要考虑当姓名的字符串首位也相同时,再通过下一位比较。
故若采用a[0].name<b[0].name判断会导致后三个测试点错误。
注:C++中字符串的比较,是通过首字母的ASCII码比较大小,如果相等比较后面的字母,以此类推
AC代码
#include<bits/stdc++.h>
using namespace std;
struct stu{
string name;
int tall;
};
bool cmp(stu a,stu b){ //将身高从高到低排序
if (a.tall!=b.tall) return a.tall>b.tall;
else return a.name<b.name; //身高相同按名字升序 ,字符串的比较是比较首字母,若首字母相同比较后一位
}
stu *print(stu *s, int num){
for(int i=num/2*2-1;i>0;i-=2){
cout<<s[i].name<<' ';
}
for(int i = 0; i < num; i += 2){
if(i) cout<<' ';
cout<<s[i].name;
}
cout<<endl;
return s+num;
}
int main(){
int n; cin>>n;
int k; cin>>k;
stu s[10001];
int p=n/k;
for(int i=0;i<n;i++){
cin>>s[i].name>>s[i].tall;
}
sort(s,s+n,cmp);
stu *sp=s;
int m=n-n/k*(k-1); //最后一排人数
sp=print(sp,m);
for(int i=1;i<k;i++){
sp=print(sp,p);
}
return 0;
}