1109 Group Photo (25 分)
题意
给出n个学生的信息(身高和姓名),要求你给这群学生排列一个队形,类似于拍毕业照的队形。队形的要求有以下几点:
1.排列有m行,每行有n/m搁学生,多余的学生排到最后一行(最后一行可以不是n/m个学生)
2.前排的学生不能比后排高
3.一排中最高的站在中间(s/2+1的位置,s为该行的总人数)
4.其他人按非递增顺序往两边排列,先左后右(如 1 2 3 4 5 排列后为 2 4 5 3 1)
5.身高相同按名字字典序递增排列,名字字典序小的先排。
输出最后的队形。(从后往前输出)
解题过程
wa了两发,一是没搞明白char字符串重载运算的问题,cmp返回的是true和false,重载中是小于号就会升序,大于号降序。char不能直接用符号比较,得用strcmp函数得出两个字符的差值(前减后),再根据差值返回true和false。
二是没考虑清楚按名字字典序小先排的概念(与我的方法得到的结果不同)我先给所有同学按身高和名字排了个序,身高相同名字字典序一样的排在前面,这里误理解为先排就应该是排在前面,后面仔细考虑发现先排是离中间最近,优先在左。修改之后就过了。
思路
给同学们排个序,高的在后,身高相同按名字字典序降序排序,名字字典序大的在前。尽可能让高的人在后面,高的人在中间,矮的人在前面与两边。
考虑每行要求高的在中间,计算一下位置。
若该行有5个人,1,2,3,4,5他们的位置应该是2 4 5 3 1,可以看出前两个人下标为递增的偶数,后三个人下表为递减的奇数。
若有4个人 1,2,3,4 他们的位置为1 3 4 2,可以看出前两个数下标为递增奇数,后两个下标为递减偶数。
分成前后两段求取每个坐标即可。
remark
题目虽然过了,但有bug,不知道是我理解岔了还是数据太水了。
题目说身高相同按字典序递增排列,看这个样例:
2 2
a 100
aa 200
b 200
c 300
我的运行结果为
aa c
a b
按题意因该为
b c
a aa
代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef struct node{
char name[101];
int height;
}node;
bool cmp(node x,node y)
{
if(x.height==y.height){
if(strcmp(x.name,y.name)>0){
return true;
}else{
return false;
}
}
return x.height<y.height;
}
node student[20007];
char fm[21][2007][11];
int n,m,row,temp=0,last; //temp前面已经排好的人数,row每行的人数,last最后一行人数
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s %d",&student[i].name,&student[i].height);
}
sort(student+1,student+n+1,cmp);
row=n/m;
for(int i=1;i<m;i++){
if(row%2==0){
for(int j=1;j<=row/2;j++){
strcpy(fm[i][j],student[temp+2*j-1].name);
}
for(int j=row/2+1;j<=row;j++){
strcpy(fm[i][j],student[temp+2*row+2-2*j].name);
}
}else{
for(int j=1;j<=(row-1)/2;j++){
strcpy(fm[i][j],student[temp+j*2].name);
}
for(int j=(row+1)/2;j<=row;j++){
strcpy(fm[i][j],student[temp+2*row+1-2*j].name);
}
}
temp+=row;
}
last=n-temp;
if(last%2==0){
for(int j=1;j<=last/2;j++){
strcpy(fm[m][j],student[temp+2*j-1].name);
}
for(int j=last/2+1;j<=last;j++){
strcpy(fm[m][j],student[temp+2*last+2-2*j].name);
}
}else{
for(int j=1;j<=(last-1)/2;j++){
strcpy(fm[m][j],student[temp+j*2].name);
}
for(int j=(last+1)/2;j<=last;j++){
strcpy(fm[m][j],student[temp+2*last+1-2*j].name);
}
}
temp+=last;
for(int j=1;j<=last;j++){
if(j!=1){
printf(" ");
}
printf("%s",fm[m][j]);
}
printf("\n");
for(int i=m-1;i>0;i--){
for(int j=1;j<=row;j++){
if(j!=1){
printf(" ");
}
printf("%s",fm[i][j]);
}
printf("\n");
}
return 0;
}