PAT A1056 Mice and Rice
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
Sample Output:
5 5 5 2 5 5 5 3 1 3 5
-
分析:
which is a permutation of 0,⋯,NP−1
第3行给出的是各位选手的出场顺序,每个数代表一个选手编号
按顺序,每Ng个人分一组(if there are less than NG mice at the end of the player's list, then all the mice left will be put into the last group.
),每组决出一个胜者,胜者继续分组决斗,直到只剩一个人 -
思路 1:
输出每个人的排名,由于每一组只选一个冠军:所以上一轮的组数,就是本轮的参赛人数,由此逆推可知,第n轮失败者的排名就是第
n轮胜者的个数+1,而胜者的个数又等于第n轮的组数
由此可得到思路 :
用一个队列实现比赛的先后顺序
每轮循环先求出组数,并将本轮所有参赛者的排名赋值为组数,失败者出队,胜者加入队尾参与下一轮,如此循环到队列中只剩一个元素(通过判断跳出循环,不加判断的话,这个元素会反复出队入队) -
code 1:
#include <iostream>
#include <stdio.h>
#include <queue>
using namespace std;
const int maxn = 1010;
queue<int> win;
int order[maxn];
struct mouse{
int weight, ra;
}mou[maxn];
int main(){
int np, ng;
scanf("%d %d", &np, &ng);
for(int i = 0; i < np; ++i){
scanf("%d", &mou[i].weight);
}
for(int i = 0; i < np; ++i){
scanf("%d", &order[i]);
}
for(int i = 0; i < np; ++i){
win.push(order[i]);
}
int numG, tmp = np;
while(!win.empty()){
//求出每轮的组数
if(tmp % ng == 0) numG = tmp / ng;
else numG = tmp / ng + 1;
int idex = 0, winner;
while(idex < tmp){
winner = 0;
int Max = 0, cnt = ng;
while(cnt > 0 && idex < tmp){
int now = win.front();
win.pop();
mou[now].ra = numG + 1;
if(mou[now].weight > Max){
Max = mou[now].weight;
winner = now;
}
cnt--; idex++;
}
win.push(winner);
}
tmp = numG;
if(tmp == 1){
mou[winner].ra = 1;
break;
}
}
for(int i = 0; i < np; ++i){
printf("%d", mou[i].ra);
if(i < np-1) printf(" ");
}
return 0;
}
- T2 code:
#include <bits/stdc++.h>
#include <queue>
using namespace std;
const int maxn = 1010;
int players[2][maxn]; //0: weight 1:rank
int main(){
int np, ng;
scanf("%d %d", &np, &ng);
for(int i = 0; i < np; ++i){
scanf("%d", &players[0][i]);
}
queue<int> win, fail;
for(int i = 0; i < np; ++i){
int now;
scanf("%d", &now);
win.push(now);
}
int sum = np;
while(sum != 1){
sum = ceil(1.0 * sum / ng);
int i = 0, j = 0, len = win.size();
while(j < len){
int winner = -1, Max = -1;
while(j < len && j - i < ng){
int tmp = win.front();
players[1][tmp] = sum + 1;
win.pop();
if(players[0][tmp] > Max){
Max = players[0][tmp];
winner = tmp;
}
j++;
}
win.push(winner);
i = j;
}
}
int final_winner = win.front();
players[1][final_winner] = 1;
for(int i = 0; i < np; ++i){
if(i == 0) printf("%d", players[1][i]);
else printf(" %d", players[1][i]);
}
return 0;
}
- T3 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2020; //要开大点,因为队列一直向一个方向伸长
int weight[maxn], ranklist[maxn], Q[maxn], f = -1, r = -1;
bool Empty(){ return f == r ? true : false; }
void Push(int x){ Q[++r] = x; }
void Pop(){ f++; }
int Top(){ if(!Empty()) return Q[f+1]; }
int Size(){ return r - f; }
int main()
{
int np, ng;
scanf("%d %d", &np, &ng);
for(int i = 0; i < np; ++i)
{
scanf("%d", &weight[i]);
}
for(int i = 0; i < np; ++i)
{
int now_player;
scanf("%d", &now_player);
Push(now_player);
}
int num_round = np;
while(Size() != 1)
{
int cnt = 0, num_group = ceil(1.0 * num_round / ng);
for(int i = 0; i < num_group; ++i)
{
int Max = -1, winner = 0;
for(int j = 0; j < ng; ++j)
{
int tmp = Top();
if(weight[tmp] > Max)
{
Max = weight[tmp];
winner = tmp;
}
ranklist[tmp] = num_group + 1;
Pop();
if(++cnt == num_round) break;
}
Push(winner);
}
num_round = num_group;
}
ranklist[Top()] = 1;
for(int i = 0; i < np; ++i)
{
printf("%d", ranklist[i]);
if(i < np - 1) printf(" ");
}
return 0;
}