PAT-B 真题- 1055. 集体照

发布于 / PAT-乙级 / 0 条评论

题干:

拍集体照时队形很重要,这里对给定的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

这道题的思路可以先将身高存储到大数组中,并排好序,然后再对每一行进行处理。

每一行处理的方法为:先让m等于中间的人在每一行的数组中的下标,然后再让m变成m-1,m+2,m-3。。。将排好序的大数组依次赋值进去即可。

具体代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

typedef struct {
    string name;
    int high;
} person;

bool cmp(person a, person b){
    if(a.high != b.high)
    return a.high < b.high;
    else return a.name > b.name;
}

int main()
{
    int sum, line, line_p; //sum为人数,line为有几行,line_p为每行的人数,last_line为最后一行的人数
    cin >> sum >> line;     //sum是总人数,line是行数
    string result[10010];    //result存储每次输出的临时数据
    int lines[15] = {0};   //每行的人数
    person p[10010];    //存储输入的数据
    line_p = sum / line;    //每行的人数(最后一排除外)
    for(int i = 0; i < sum; i++){
        cin >> p[i].name >> p[i].high;  //依次读入数据
    }
    sort(p, p + sum, cmp);  //将数组p中的元素按照题意进行排序 小->大
    int s = sum;            //s为临时变量
        //下面这一段循环可以用memset替代,只要注意特殊考虑最后一行就行
    for(int i = 0; i < line; i++){
        if(i != line - 1){  //只要不是最后一行,这一行的人数就是line_p
            lines[i] = line_p;
            s -= line_p;
        }else{      //如果是最后一行
            lines[i] = s;   //最后一行人数等于剩下的人数
        }
    }            //到此,lines内部元素为从前到后排好序了
    int n, it = sum - 1, middle;   //n是系数,cnt用来计数,it为当前在数组的位置,middle用来存储中间的人的下标
    for(int i = line - 1; i >= 0; i--){ //从后到前进行排列
        n = 1; middle = (lines[i] / 2); //每次循环初始化一遍数据
        for(int j = 0; j < lines[i]; j++){
            middle += j * n;
            result[middle] = p[it--].name;
            n *= -1;
        }
        for(int k = 0; k < lines[i]; k++){
            cout<<result[k];
            if(k != lines[i] - 1) cout<<' ';
    }
    cout<<endl;
    }
    return 0;
}

转载原创文章请注明,转载自: 斐斐のBlog » PAT-B 真题- 1055. 集体照
目前还没有评论,快来抢沙发吧~