PAT 甲级 1056 Mice and Rice 思路以及解题代码

Problem

Mice and Rice is the name of a programming contest in which each programmer must write a piece of code to control the movements of a mouse in a given map. The goal of each mouse is to eat as much rice as possible in order to become a FatMouse.
(第一段相当于故事背景,没啥用。。)
First the playing order is randomly decided for N​P​​ programmers. Then every N​G​​ programmers are grouped in a match. The fattest mouse in a group wins and enters the next turn. All the losers in this turn are ranked the same. Every N​G​​ winners are then grouped in the next match until a final winner is determined.
(第二、三段来说明一下游戏规则)意思就是一共有NP个老鼠,每NG个一组,最后不够NG个的,单独分一组,每一轮中每组胜利的那一个进入下一轮,该轮失败的所有老鼠,他们的排名是相同的,一直这样做,直到剩下最后一个。排名第一,依次类推。
For the sake of simplicity, assume that the weight of each mouse is fixed once the programmer submits his/her code. Given the weights of all the mice and the initial playing order, you are supposed to output the ranks for the programmers.
为了使问题简单化,假设每个老鼠的重量是不变的,输入是老鼠的重量以及老鼠的排列序号,需要输出最终每个老鼠的排名。

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N​P​​ and N​G​​ (≤1000), the number of programmers and the maximum number of mice in a group, respectively. If there are less than N​G​​ mice at the end of the player’s list, then all the mice left will be put into the last group. The second line contains N​P​​ distinct non-negative numbers W​i​​ (i=0,⋯,N​P​​−1) where each W​i​​ is the weight of the i-th mouse respectively. The third line gives the initial playing order which is a permutation of 0,⋯,N​P​​−1 (assume that the programmers are numbered from 0 to N​P​​−1). All the numbers in a line are separated by a space.
每一个输入包括三行,第一行是NP和NG的值,分别代表的是老鼠的个数以及每个组的大小。第二行中每个老鼠的重量是互不相同的,第三行是每个老鼠的排列序号,或者说是出场顺序。(说不清楚,请看我下面的例子解析。)

Output Specification:

For each test case, print the final ranks in a line. The i-th number is the rank of the i-th programmer, and all the numbers must be separated by a space, with no extra space at the end of the line.
常规输出要求。不细说了。

Sample Input:

11 3
25 18 0 46 37 3 19 22 57 56 10 这一行代表的是每个老鼠的重量。
6 0 8 7 10 5 9 1 4 2 3 //这一行第一个数代表的是第6号老鼠第一出场。0号老鼠第二出场。

Sample Output:

5 5 5 2 5 5 5 3 1 3 5

我的思路

定义一个map表示一个老鼠的重量和输出序号,默认都初始化为1。
定义一个队列,按照第三行的顺序把对应的元素push进去。
然后,每NG个一组,找出最大值,最大值,加入队列,普通值加入一个栈,每次一轮结束之后,输出栈的元素,并赋值为当前队列的大小加1。
(大致是这样,具体细节处理,见下面代码。)

My Solution

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstring>
#include <map>
#include <iterator>
using namespace std;
#pragma warning(disable:4996)

int main()
{
	map<int, int>map1;
	int m = 0;
	int n = 0;
	cin >> m >> n;
	int a[1000] = { 0 };
	for (int i = 0; i < m; i++) {
		cin >> a[i];
	}
	//首先初始化每个老鼠的输出序号是1
	for (int i = 0; i < m; i++) {
		map1[a[i]] = 1;       
	}
	queue<int>d;
	int c = 0;
	for (int i = 0; i < m; i++) {
		cin >> c;
		d.push(a[c]);
	}
	int b[1000] = { 0 };
	int i1 = 0;
	stack<int>d2;
	while (d.size()!=1) {
		int j = d.size();
		for (int j1 = 0; j1 < j; j1=j1+n) {
			for (i1 = 0; i1 < n; i1++) {
				if (j1+i1<j) {
					b[i1] = d.front();
					d.pop();
				}
				else break;
			}
			int max = -1;
			//找到那个最大值。
			for (int i = 0; i < i1; i++) {
				if (b[i] > max) { max = b[i]; }
			}
			for (int i = 0; i < i1; i++) {
				if (b[i] != max) { d2.push(b[i]); }
				else { d.push(b[i]); }
			}
		}
		int j3 = d.size();
		while (!d2.empty()) {
			map1[d2.top()] = j3 + 1;
			d2.pop();
		}
	}
	cout << map1[a[0]];
	for (int i = 1; i < m; i++) {
		cout << " " << map1[a[i]];
	}
	return 0;
}

另外,我看了算法笔记的解法,他使用结构体表示一个老鼠,其中一个元素是排名,就没有像我这样使用map,另外,他还注意到每轮的组数+1就是该轮被淘汰的老鼠的排名,这也是很仔细,优化了我代码中计算排名的那部分。其他的意思差不多。如果需要算法笔记的源码,可以CSDN私信我,或者留言。谢谢阅读!

发布了27 篇原创文章 · 获赞 0 · 访问量 404

猜你喜欢

转载自blog.csdn.net/weixin_40007143/article/details/104189490