1056 Mice and Rice (25 分)

MiceandRice是一项编程比赛,参赛者编写控制鼠标在地图上移动的代码,目标是让鼠标吃尽可能多的大米。比赛通过多轮淘汰制决定最终胜者,本文介绍了比赛规则和一种用于确定参赛者排名的算法。

 

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.

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.

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

Sample Output:

5 5 5 2 5 5 5 3 1 3 5

C++:

/*
 @Date    : 2018-01-30 13:49:28
 @Author  : 酸饺子 (changzheng300@foxmail.com)
 @Link    : https://github.com/SourDumplings
 @Version : $Id$
*/

/*
https://www.patest.cn/contests/pat-a-practise/1056
 */

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

struct P
{
    P(int w): W(w), rank(1) {}
    int W;
    int rank;
};

P* play(const vector<P*> &about_to_play)
{
    int max_W = 0;
    P* winner;

    // printf("Now playing: \n");
    // for (const auto &p : about_to_play)
    //     cout << p->W << " ";
    // putchar('\n');

    for (const auto &p : about_to_play)
    {
        if (p->W > max_W)
        {
            max_W = p->W;
            winner = p;
        }
    }
    return winner;
}

// int circles;

int main(int argc, char const *argv[])
{
    vector<P> data;
    queue<P*> survived;
    int NP, NG;
    scanf("%d %d", &NP, &NG);
    int Wi;
    for (int i = 0; i != NP; ++i)
    {
        scanf("%d", &Wi);
        data.push_back(P(Wi));
    }
    int temp;
    for (int i = 0; i != NP; ++i)
    {
        scanf("%d", &temp);
        survived.push(&data[temp]);
    }

    while (survived.size() > 1)
    {
        // ++circles;
        // printf("In the circle %d: \n", circles);

        queue<P*> next_to_play;
        queue<P*> loser;

        for (int played = 0; played != NP && !survived.empty();)
        {
            vector<P*> about_to_play;
            for (int poped = 0; poped != NG; ++poped)
            {
                if (survived.empty())
                    break;
                P* next_P = survived.front();
                survived.pop();
                about_to_play.push_back(next_P);
            }

            P* winner;
            winner = play(about_to_play);
            next_to_play.push(winner);
            played += about_to_play.size();
            for (auto &each_loser : about_to_play)
            {
                if (each_loser != winner)
                    loser.push(each_loser);
            }

            // printf("played = %d, NP = %d\n", played, NP);
        }

        while (!loser.empty())
        {
            loser.front()->rank += next_to_play.size();
            loser.pop();
        }

        while (!next_to_play.empty())
        {
            P* next_P = next_to_play.front();
            next_to_play.pop();
            survived.push(next_P);
        }

    }

    int output = 0;
    for (int i = 0; i != NP; ++i)
    {
        if (output++)
            putchar(' ');
        printf("%d", data[i].rank);
    }
    putchar('\n');

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值