题目
拍集体照时队形很重要,这里对给定的N个人K排的队形设计排队规则如下:
- 每排人数为N/K(向下取整),多出来的人全部站在最后一排;
- 后排所有人的个子都不比前排任何人矮;
- 每排中最高者站中间(中间位置为m/2+1,其中m为该排人数,除法向下取整);
- 每排其他人以中间人为轴,按身高非增序,先右后左交替入队站在中间人的两侧(例如5人身高为190、188、186、175、170,则队形为175、188、190、186、170。这里假设你面对拍照者,所以你的左边是中间人的右边);
- 若多人身高相同,则按名字的字典序升序排列。这里保证无重名。
现给定一组拍照人,请编写程序输出他们的队形。
输入格式:
每个输入包含1个测试用例。每个测试用例第1行给出两个正整数N(<=10000,总人数)和K(<=10,总排数)。随后N行,每行给出一个人的名字(不包含空格、长度不超过8个英文字母)和身高([30, 300]区间内的整数)。
输出格式:
输出拍照的队形。即K排人名,其间以空格分隔,行末不得有多余空格。注意:假设你面对拍照者,后排的人输出在上方,前排输出在下方。
输入样例:
10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159
输出样例:
Bob Tom Joe Nick
Ann Mike Eva
Tim Amy John
实现思路:
1.定义结构体数组,存入数据;
2.按照身高由高到低和名字快速排序;
3.定义排数组,从最后一排开始按照规定排序循环赋值输出,规定排序可理解为从中间位置开始,依次位置依次-1,+2,-3,……。
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//结构体
typedef struct{
char szName[9];
int iHight;
} PEOPLE;
//快排比较函数
int cmp(const void *a, const void *b)
{
int iFlag=0;
PEOPLE *p=(PEOPLE *)a;
PEOPLE *q=(PEOPLE *)b;
if(p->iHight<q->iHight)
{
iFlag=1;
}
else if(p->iHight==q->iHight)
{
if(strcmp(p->szName,q->szName)>0)
{
iFlag=1;
}
else
{
iFlag=-1;
}
}
else
{
iFlag=-1;
}
return iFlag;
}
//输出函数
void print(PEOPLE *p, int len)
{
for(int i=0;i<len;i++)
{
if(i==0)
{
printf("%s",p[i].szName);
}
else
{
printf(" %s",p[i].szName);
}
}
}
int main()
{
int iNum=0,iK=0;
scanf("%d%d",&iNum,&iK);
PEOPLE people[iNum];//输入数据
for(int i=0;i<iNum;i++)
{
scanf("%s %d",&people[i].szName,&people[i].iHight);
}
qsort(people,iNum,sizeof(people[0]),cmp);//快速排序
PEOPLE last[iNum/iK+iNum%iK],temp[iNum/iK];//定义最后一排和其他排的临时数组
int pos=(iNum/iK+iNum%iK)/2,flag=1,p=0,q=0;//定义中间位置和标记变量
for(int i=0;i<iNum/iK+iNum%iK;i++)
{
pos=pos+flag*p;
last[pos]=people[q++];
flag=-flag;
p++;
}
print(last,iNum/iK+iNum%iK);输出最后一排
if(iK>1)
{
printf("\n");
for(int j=0;j<iK-1;j++)
{
pos=iNum/iK/2,flag=1,p=0;//定义中间位置和标记变量
for(int i=0;i<iNum/iK;i++)
{
pos=pos+flag*p;
temp[pos]=people[q++];
flag=-flag;
p++;
}
print(temp,iNum/iK);
if(j!=iK-2)
{
printf("\n");
}
}
}
return 0;
}
错误分析:
1.快排函数的比较函数中名字的比较最好用strcmp,不能只比较第一个字母;
2.题目中的中间位置是从1开始计算的,而数组是从0开始,所以中间位置减1。