PAT A1109 Group Photo

题目描述

在这里插入图片描述
题目实在是太长了。。。

知识点

排序

实现

码前思考

  1. 就是使用sort函数进行排序的一个题目。。。

代码实现

#include "bits/stdc++.h"
using namespace std;

const int maxn = 10;
const int maxm = 1e4+10;

int n;
int k;

struct person{
	char name[maxn];
	int height;
}p[maxm];

bool cmp(person a,person b){
	if(a.height < b.height){
		return true;
	}else if(a.height == b.height){
		if(strcmp(a.name,b.name) > 0){
			return true;
		}else{
			return false;
		}
	}else{
		return false;
	}
}

int main(){
	scanf("%d %d",&n,&k);
	
	//开始读入数据
	for(int i=0;i<n;i++){
		scanf("%s %d",&p[i].name,&p[i].height);
	}
	
	//读完之后进行排序
	sort(p,p+n,cmp);

	//排完序之后再进行排序
	if(n < k){
		//直接输出
		int start = 0; 
		//结束的编号 
		int end = n-1; 
		person tmp[n];  
		int len = n;
		int isR = true;
		 
		//首先找到最高的那一位
		tmp[(len/2)] = p[end];
		int l = (len/2)+1;
		int r = (len/2)-1;
		for(int i=end-1;i>=start;i--){
			if(isR){
				tmp[r] = p[i];
				r = r-1;
				isR = false;
			}else{
				tmp[l] = p[i];
				l = l+1;
				isR = true;
			}
		}
		//进行输出
		for(int j=0;j<len;j++){
			printf("%s%c",tmp[j].name,j!=len-1 ? ' ':'\n');
		}		
	}else{
		//从最后一组开始进行输出		
		//初始化 
		//组的编号
		int no = k-1;
		//开始的编号 
		int start = no*(n/k); 
		//结束的编号 
		int end = n-1; 
		for(;no>=0;no--){
			//一个临时用于输出的数组
			person tmp[(n/k)*2]; 
			int len = end - start + 1;
			int isR = true; 
			//首先找到最高的那一位
			tmp[(len/2)] = p[end];
			int l = (len/2)+1;
			int r = (len/2)-1;
			for(int i=end-1;i>=start;i--){
				if(isR){
					tmp[r] = p[i];
					r = r-1;
					isR = false;
				}else{
					tmp[l] = p[i];
					l = l+1;
					isR = true;
				}
			}
			//进行输出
			for(int j=0;j<len;j++){
				printf("%s%c",tmp[j].name,j!=len-1 ? ' ':'\n');
			}
			
			//更新start和end
			end = start-1;
			start = (no-1) * (n/k); 
		} 
	} 
	
	return 0;
} 

码后反思

  1. 我的代码果然是又臭又长。。。
  2. 关于strcmp()函数的用法,我还没有掌握清楚。我在字符数组使用里面做了整理。
  3. 其实可以使用string来记录姓名的,这样比较两个字符串就可以直接使用<了。
  4. 关于身高相同时的排序,题目中的所说的按照名字的字典序升序,是指在进行每一行的排列时,对于相同的身高,应该先排字典序小的,所以这就导致了在原始sort排序时,我们应该把字典序小的排在字典序大的后面这个可以结合样例进行理解
  5. 需要考虑一下N<K的时候应该怎么进行操作,柳婼的代码没有进行考虑(但是她的代码依然很漂亮!):
    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    struct node {
        string name;
        int height;
    };
    int cmp(struct node a, struct node b) {
        return a.height != b.height ? a.height > b.height : a.name < b.name;
    }
    int main() {
        int n, k, m;
        cin >> n >> k;
        vector<node> stu(n);
        for(int i = 0; i < n; i++) {
            cin >> stu[i].name;
            cin >> stu[i].height;
        }
        sort(stu.begin(), stu.end(), cmp);
        int t = 0, row = k;
        while(row) {
            if(row == k) {
                m = n - n / k * (k - 1);
            } else {
                m = n / k;
            }
            vector<string> ans(m);
            ans[m / 2] = stu[t].name;
            // 左边一列
            int j = m / 2 - 1;
            for(int i = t + 1; i < t + m; i = i + 2)
                ans[j--] = stu[i].name;
            // 右边一列
            j = m / 2 + 1;
            for(int i = t + 2; i < t + m; i = i + 2)
                ans[j++] = stu[i].name;
            // 输出当前排
            cout << ans[0];
            for(int i = 1; i < m; i++)
                cout << " " << ans[i];
            cout << endl;
            t = t + m;
            row--;
        }
        return 0;
    }
    
  6. 柳神直接按照身高递减排序,很妙,这样减少了不小的思维量。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值