PAT甲级 1056 Mice and Rice(25)

文章目录


题目

原题链接



题目大意

给定参赛的老鼠数量为N~P~,每N~G~只老鼠分为一组,组中最胖的老鼠获胜,并进入下一轮,所有在本回合中失败的老鼠排名都相同,获胜的老鼠继续每N~G~只一组,进行比赛,直到决出唯一胜者为止。

输入格式

第一行包含两个整数 N~P~ 和 N~G~,分别表示老鼠的总数量以及每组老鼠的最大数量。如果分组到最后,剩下不足 N~G~ 只老鼠,则剩下的所有老鼠分为一组。所有 N~P~ 只老鼠的编号为0 ~ N~P~-1。

第二行包含 N~P~ 个不同的非负整数W~i~ (i=0,1,...N~P~-1),其中 W~i~ 表示编号为 i 的老鼠的重量。

第三行包含一个0 ~ N~P~-1的排列,表示老鼠的具体参赛顺序,以样例为例,6号老鼠排在第一个,0号老鼠排在第二个,以此类推。

输出格式

输出一行 N~P~ 个整数,其中第 i 个整数表示编号为 i 的老鼠的最终排名。

数据范围

1 ≤ N~P~ ≤ 1000 ,2 ≤ N~G~ ≤ 1000,0 ≤ W~i~ ≤ 1000。

基本思路

在进行每轮比赛时,都要先划分小组,在每个小组里选出最重的老鼠进入下一轮比赛,因为每个小组都会筛选出一个最重的老鼠,而其它老鼠的排名就为这轮比赛的组数+1,比如一共有四个老鼠,每组最多三只,则分成两组,每组筛选一个最重的老鼠,就剩下两只老鼠并列第三名(当前组数+1)。还有两只老鼠进入下一轮比赛,因为不足三只,则分成一组,从里面筛选出最重的老鼠成为最终获胜者,则另一只老鼠就为第二名(当前组数+1)。

先定义一个结构体mouse用来存储老鼠的重量和排名,接着定义一个结构体数组m来存储每只老鼠的信息。

cpp 复制代码
struct mouse {
	int weight;//重量
	int rank;//排名
}m[N];

用一个队列q将每只老鼠的编号按参赛顺序依次入队,使用while循环控制比赛的轮数,当队列只有一只老鼠的编号时,说明已经筛选出最终获胜的老鼠,直接退出循环即可,因此,进入的循环条件为q.size()>1

在循环里,需要先计算当前的老鼠数量能够分几组,然后再枚举每一组,选出每组中重量最大的老鼠并将其编号记录下来,再将同一组里所有老鼠的排名赋值为当前组数+1,然后将其出队(因为筛选出来的老鼠会进行下一轮比赛,它们的排名会重新变化 ),再将记录下来的重量最大的老鼠的编号重新进行入队。

注意

  1. 因为最后一组的老鼠数量可能不足 N~G~ 只,所以每次筛选出一组中重量最大的老鼠时,要判断当前老鼠的次序是否小于老鼠的总数量,如果大于等于老鼠的总数量则直接退出内层循环。
cpp 复制代码
for (int i = 0; i < group; i++)
{
	int t = q.front();
	for (int j = 0; j < ng; j++)
	{
	    //判断当前老鼠的次序是否小于老鼠的总数量,如果大于或等于则直接退出循环
		if (i * ng + j >= temp)
		{
			break;
		}
		int tt = q.front();
		if (m[t].weight < m[tt].weight)
		{
		    //更新
			t = tt;
		}
		m[tt].rank = group + 1;
		q.pop();
	}
	q.push(t);
}
  1. 每轮比赛过后,因为有些老鼠要进入下一轮比赛,所以老鼠的数量都会发生变化,再进行下一轮比赛前(因为要分组),需要将老鼠的总数量更新为当前比赛的组数(因为有几组就会晋升几只老鼠)。
cpp 复制代码
while (q.size() > 1)
{
	int group;
	if (temp % ng == 0) group = temp / ng;
	else group = temp / ng + 1;
	for (int i = 0; i < group; i++)
	{
		int t = q.front();
		for (int j = 0; j < ng; j++)
		{
			//判断当前老鼠的次序是否小于老鼠的总数量,如果大于或等于则直接退出循环
			if (i * ng + j >= temp)
			{
				break;
			}
			int tt = q.front();
			if (m[t].weight < m[tt].weight)
			{
				//更新
				t = tt;
			}
			m[tt].rank = group + 1;
			q.pop();
		}
		q.push(t);
	}
    //进入下一轮比赛的老鼠总数量为当前组数
	temp = group;
}

AC代码

cpp 复制代码
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1010;
struct mouse {
	int weight;//重量
	int rank;//排名
}m[N];
int main()
{
	int np, ng;
	cin >> np >> ng;
	int temp = np;
	for (int i = 0; i < np; i++)
	{
		cin >> m[i].weight;
	}
	queue<int> q;
	for (int i = 0; i < np; i++)
	{
		int x;
		cin >> x;
		q.push(x);
	}
	while (q.size() > 1)
	{
		int group;
		if (temp % ng == 0) group = temp / ng;
		else group = temp / ng + 1;
		for (int i = 0; i < group; i++)
		{
			int t = q.front();
			for (int j = 0; j < ng; j++)
			{
			    //判断当前老鼠的次序是否小于老鼠的总数量,如果大于或等于则直接退出循环
				if (i * ng + j >= temp)
				{
					break;
				}
				int tt = q.front();
				if (m[t].weight < m[tt].weight)
				{
				    //更新
					t = tt;
				}
				m[tt].rank = group + 1;
				q.pop();
			}
			q.push(t);
		}
		//进入下一轮比赛的老鼠总数量为当前组数
		temp = group;
	}
	
	//将最终获胜的老鼠的排名记为第一名
	m[q.front()].rank = 1;
	
	cout << m[0].rank;
	for (int i = 1; i < np; i++)
	{
		cout << " " << m[i].rank;
	}
	return 0;
}

在PAT和AcWing平台都通过了

总结

这道题不是难理解,生词也比较少,比较难的是给每只老鼠排名,要结合样例和自己模拟一遍过程得出结论:排名 = 组数 + 1。最后不要忘了更新老鼠的总数量和遍历到当前老鼠的次序不超过总数量即可。

相关推荐
风_流沙几秒前
python 对MySQL操作封装工具类
开发语言·python·mysql
SyntaxSage21 分钟前
Ruby语言的多线程编程
开发语言·后端·golang
牛马程序员‍22 分钟前
云商城--业务+架构学习和环境准备
java·开发语言
oulaqiao24 分钟前
以C++为基础快速了解C#
开发语言·c++·c#
Vec[95]37 分钟前
如何将光源视角的深度贴图应用于摄像机视角的渲染
c++·算法·3d·贴图
雾削木41 分钟前
C# WPF Material DesignThemes 5.0 命名规则改变后导致找不到资源
开发语言·c#·wpf
DevOpsDojo43 分钟前
Bash语言的并发编程
开发语言·后端·golang
矮油0_o1 小时前
Ⅱ.INTRODUCTION TO CUDA C (CUDA C 入门)
c语言·开发语言·gpu算力·cuda c
天弈初心1 小时前
python:利用神经网络技术确定大量离散点中纵坐标可信度的最高集中区间
开发语言·python·神经网络
醒了就刷牙1 小时前
黑马Java面试教程_P11_技术场景
java·开发语言·面试