您的位置:首页 > 其它

1055. 集体照 (25)

2017-11-21 16:13 351 查看

原题: https://www.patest.cn/contests/pat-b-practise/1055

思路: 先从大到小排序(名字相同的也考虑上), 然后分排分别遍历, 第一次要遍历
的人数需要加上剩余的人数, 也就最后一排所有的人数, 之后每排的人数都相等.

题目中说的先插左边后插右边, 不需要奇偶判断, 用if和elseif就行.

实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 10010

struct Class {
char name[10];
int height;
};
typedef struct Class class;
int compare (const void *a, const void *b);
int main (void) {
int zrs;        // 总人数
int zps;        // 总排数
int gprs;       // 该排人数
int midpos;     // 中间位置
class src[LEN]; // 下标0不用
class dest[LEN];
int i;

scanf("%d %d", &zrs, &zps);
for (i = 1; i <= zrs; i++) {
scanf("%s %d", src[i].name, &src[i].height);
}
qsort(src + 1, zrs, sizeof(class), compare);

int startpos = 1; // 开始位置
int j;
int left;      // 插入左边
int right;     // 插入右边
int leftpos;   // 左位置
int rightpos;  // 右位置
for (i = 1; i <= zps; i++) {
if (i == 1) {
gprs = (zrs / zps) + (zrs % zps);
} else {
gprs = zrs / zps;
}
midpos = gprs / 2 + 1;
dest[midpos] = src[startpos];
left = 1;
right = 0;
leftpos = midpos;
rightpos = midpos;
// 每次一段段的循环该排人数
// 把该排人的位置调整后放入 dest 中
for (j = startpos + 1; j <= startpos + gprs - 1; j++) {
if (left == 1) {
dest[--leftpos] = src[j];
left = 0;
right = 1;
} else if (right == 1) {
dest[++rightpos] = src[j];
left = 1;
right = 0;
}
}
char ch = ' ';
for (j = 1; j <= gprs; j++) {
if (j == gprs) ch = '\n';
printf("%s%c", dest[j].name, ch);
}
startpos += gprs;
}

return 0;
}

int compare (const void *a, const void *b) {
class arg1 = *(class*)a;
class arg2 = *(class*)b;

if (arg1.height != arg2.height) {
return arg2.height - arg1.height;
} else {
return strcmp(arg1.name, arg2.name);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: