1055 集体照 (25 分)

题目

题目链接

题解

模拟。


之所以样例输出如此,是因为第一行其实是排队的最后一排,样例的输出更像是一张俯视图,我们站在最后一行的下一行去给他们拍照,他们面朝下,我们面朝上。

至于题目中说的“这里假设你面对拍照者,所以你的左边是中间人的右边”,就理解成每行都是按照先选出最高的人,队伍的最左端(我们的视角)插入一个次高的,再向队伍右端插入一个次次高的……


先排序。

我是以步长为2分别从右向左、从左向右遍历排好序的每个人,直接输出就行了;但是要注意分该行的人数是奇数还是偶数,奇数和偶数对应的遍历边界不一样。


为什么我实现代码这么慢?脑子太笨,沃日。

代码

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

int n, k, m, l;
struct node {
	string name;
	int h;
} a[10010];

bool cmp (node a, node b) {
	if (a.h != b.h) return a.h > b.h;
	return a.name < b.name;
}

int main()
{
	cin >> n >> k;
	for (int i = 0;i < n;i ++) cin >> a[i].name >> a[i].h;
	sort (a, a+n, cmp);
	
	for (int t = 0;t < k;t ++) {
		m = n / k + n % k; // 该行的人数 
		n -= n % k; // 如果n整除k了每次n就不变了 
		
		int r = l + m - 1, flag = 0; // l和r分别控制该行人的索引的左端点与右端点 
//		cout << l << ' ' << r << endl;
		for (int i = r - (m & 1);i >= l;i -= 2) { // 每次隔着一个人枚举,如果该行的人数为奇数,那么就要从r的前一个开始向前推 
			if (flag) cout << ' ';
			flag = 1;
			cout << a[i].name;
		}
		for (int i = l;i <= r;i += 2) { // 也是每次隔一个人 
			if (flag) cout << ' ';
			flag = 1;
			cout << a[i].name;
		}
		l = r + 1; // 更新l 
		cout << endl;		
	}	

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不牌不改

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

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

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

打赏作者

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

抵扣说明:

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

余额充值