1055 集体照 (25 分)(算法分析+代码实现)

1055 集体照 (25 分)

题目链接

算法分析

本身题目不难理解,但是实现起来比较繁琐。在我的代码里核心的处理思想

一、用map建立一个链表结构

我们根据题目的要求可知,假设编号1到n的同学身高已经降序排列,那么他们从左往右(输出时的顺序)为:
… … 8 − 6 − 4 − 2 − 1 − 3 − 5 − 7 − 9 … … ……8-6-4-2-1-3-5-7-9…… 864213579
因此我们可以初始化这样一个大小为n的链表,然后在每一行输出时,首先求出这一行的学生个数,然后得到不大于这个数的最大偶数,然后从左往右依次处理:1.输出当前同学的名字 2.用链表把位置调到下一个同学的位置。然后直至结束。

二、使用一个“势能”的概念

具体来讲,就是我们每一次获得当前行的学生个数后,虽然我们通过链表得到了对应同学的编号,但是与它在结构体数组中的下标不一致,恰好相差,当前行之前的所有行总共的学生个数。

代码实现

#include<bits/stdc++.h>
using namespace std;
#define N 10005
struct student{
	string name;
	int height;
}stu[N];
bool cmp(student a, student b){
	return a.height == b.height ? a.name < b.name : a.height > b.height;
}
int n, k;
map< int , int >mp;
void init(int m){
	if(m % 2 == 1) m -= 1;
	int n0 = n;
	while(n0 --){
		if(m % 2 == 0 && m != 2){
			mp[m] = m - 2;
			m -= 2;
		}
		else if(m == 2){
			mp[m] = 1;
			m -= 1;
		}
		else{
			mp[m] = m + 2;
			m += 2;
		}
	}
	return ;
}
void print(int l, int h){
	int x = l;
	if(l != 1 && l % 2 == 1) x -= 1;
	for(int i = 1; i <= l; ++ i){
		cout<< stu[x + h].name;
		x = mp[x];
		if(i < l) printf(" ");
		else printf("\n");
	}
	return ;
}
int main(){
	scanf("%d%d", &n, &k);
	init(n);
	for(int i = 1; i <= n; ++ i)
		cin>> stu[i].name>> stu[i].height;
	sort(stu + 1, stu + n + 1, cmp);
	int h = 0;//势能
	for(int i = 1; i <= k; ++ i){
		int l = n / k;
		if(i == 1) l += n % k;//多出的同学补到最后一排
		print(l, h);
		h += l;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Crer_lu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值