PAT-A 1056 Mice and Rice (25)

  简单模拟。使用队列模拟流程。

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 NG winners are then grouped in the next match until a final winner is determined.

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.

Problem: PAT-A 1056 Mice and Rice

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 Wi 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.

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

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

Sample Output

1
5 5 5 2 5 5 5 3 1 3 5

Analysis

  题目大意:有 $N_P$ 个程序猿,每只程序猿一只老鼠,参加老鼠比重量的比赛。每轮比赛划分多个组,每组 $N_G$ 位选手,如果最后剩余不足 $N_G$ 数量的选手也组成一组。每组中最重的老鼠晋级参加下一轮。要求计算出参赛选手的排名,其中同一轮的失败者名次并列。

  按照题意模拟就 vans 了。数据读入第二行为每只老鼠的重量,第三行为老鼠的序号,因此需要先将序号与选手匹配(我用了 map )。使用队列存放参赛选手,不断从队列取老鼠,每 $N_G$ 只判断一次获胜者,并添加至队列末端,对最后的不足 $N_G$ 选手的组也要判断。需要确定每一轮的 $N_P$,即总参赛鼠数,同时更新排名数据。详情见代码。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <bits/stdc++.h>
using namespace std;

struct mic {
int idx, weit, ranc; // 序号, 重量, 排名
};

map<int, mic> mp;
queue<mic> que;

int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int NP, NG;
cin >> NP >> NG;
vector<int> W(NP);
for (int i = 0; i < NP; i++) {
cin >> W[i];
}
for (int i = 0; i < NP; i++) {
int idx;
mic m;
cin >> idx;
m.idx = idx;
m.weit = W[idx];
que.push(m);
mp[idx] = m;
}
int cnt = 0, rk = ceil(NP * 1.0 / NG) + 1, mxW = -1, mxW_id;
while (!que.empty()) {
mic mm = que.front();
que.pop();
if (mm.weit > mxW) { // 获取当前组最重数据
mxW = mm.weit;
mxW_id = mm.idx;
}
mp[mm.idx].ranc = rk; // 更新排名
cnt++;
if (cnt % NG == 0 || cnt == NP) { // 一组结束
que.push(mp[mxW_id]); // 添加获胜者至队尾
mxW = -1;
if (cnt == NP) { // 本轮结束
NP = que.size(); // 更新选手数量
if (NP == 1) { // 只剩一老鼠,结束循环
mp[mxW_id].ranc = 1;
break;
}
rk = ceil(NP * 1.0 / NG) + 1; // 计算下一组失败者名次
cnt = 0;
}
}
}
int flag = 0;
for (auto &i : mp) {
if (flag) cout << " ";
cout << i.second.ranc;
flag++;
}
}

Tsukkomi

  题目比较简单,但是读了好几遍才读懂,起初没明白输入第三行是干啥的,就很烦。第一遍代码写得逻辑很乱以为过不了,居然过了。改了改感觉还是不清晰,有缘再改吧。


#
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×