【题解】【AcWing】1542. 老鼠和大米

169 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1542. 老鼠和大米

原题传送:AcWing 1542. 老鼠和大米

老鼠和大米是一个编程竞赛的主题,程序员们需要编写代码控制老鼠在给定的地图上移动,每只老鼠的目标都是吃掉尽可能多的大米,从而变成肥老鼠。

共有 NPN_P 个程序员参赛,入场顺序随机,每 NGN_G 个程序员被分为一组。

组中最胖的老鼠获胜,并进入下一轮。

所有在本回合中失败的老鼠排名都相同。

获胜者继续每 NGN_G 个一组,进行比赛,直到决出唯一胜者为止。

为了简单起见,当程序员们提交了代码后,他们的老鼠的最终重量就已经确定了。

给定所有老鼠的重量和程序员们的参赛顺序,请你为程序员们排名。

输入格式

第一行包含两个整数 NPN_PNGN_G ,分别表示总参赛人数以及每组最多人数。

如果分组到最后,剩下不足 NGN_G 个人,则剩下的所有人分为一组。

所有 NPN_P 只老鼠的编号为 0NP10 \sim N_P-1

第二行包含 NPN_P 个不同的非负整数 Wi(i=0,1,,NP1)W_i(i=0,1,…,N_P-1) ,其中 WiW_i 表示编号为 ii 的老鼠的重量。

第三行包含一个 0NP10 \sim N_P-1 的排列,表示老鼠的具体参赛顺序,以样例为例, 66 号老鼠排在第一个, 00 号老鼠排在第二个,以此类推。

输出格式

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

数据范围

1NP10001 \le N_P \le 10002NG10002 \le N_G \le 1000 , 0Wi10000 \le W_i \le 1000

输入样例:

11 3
25 18 0 46 37 3 19 22 57 56 10
6 0 8 7 10 5 9 1 4 2 3

输出样例:

5 5 5 2 5 5 5 3 1 3 5

思路:

每一轮找出各组的最大值,获胜者进入下一轮,剩下的计算排名,每一轮老鼠的排名是本轮获胜数量+1,最后剩下的是第一名。

题解:

#include<bits/stdc++.h>

using namespace std;

const int N = 1010;

int main()
{	
	int n, m;
	int w[N], rank[N];

	cin >> n >> m;
	vector<int> cur(n);

	for(int i = 0; i < n; i++)
		cin >> w[i];
	
	for(int i = 0; i < n; i++)
		cin >> cur[i];
		
	while(cur.size() > 1)
	{
		vector<int> next;
		int remain = (cur.size() + m - 1) / m;
		
		for(int i = 0; i < cur.size();)
		{
			int j = min((int)cur.size(), i + m);
			
			int t = i;
			for(int k = i; k < j; k++)
				if(w[cur[k]] > w[cur[t]])
					t = k;
			next.push_back(cur[t]);
			for(int k = i; k < j; k++)
				if(k != t)
					rank[cur[k]] = remain + 1;
				
			i = j;
		}
		cur = next;
	}
	
	rank[cur[0]] = 1;
	
	cout << rank[0];
	for(int i = 1; i < n; i++)
		cout << " " << rank[i];
	cout << endl;

	return 0;
}