【ACM】PAT. A1056 Mice and Rice 【队列】

题目链接
题目分析

line2:Mice 重量 (输入顺序即为Mice的编号)
line3:参加比赛的Mice顺序

解题思路

两个数组,分别记录Mice重量,和Mice游戏的序号

player[]: 记录line2给出的 Mice的重量
playing_order[]: 记录lin3给出的游戏序号,并在每一轮更新

1、每次筛选时用player 的下标数组playing_order[]操作即可

2、排名次:每一轮筛选出countRest个选手,则这一轮落选的选手名次都是 (countRest + 1)


AC程序(C++)
/**************************
*@Author: 3stone
*@ACM: PAT.A1056. Mice and Rice   
*@Time: 18/7/19
*@IDE: VSCode2018
***************************/
#include<cstdio>
#include<cstring>

#define maxSize 1010

using namespace std;

struct Node{
    int order, weight;
}player[maxSize];

int playing_order[maxSize], rest_order[maxSize];

//查找st-ed范围内的最大值,返回下标
//顺带把落选者的名次 赋了
int getMax(int st, int ed, int ranks) {
    int mx = -1, key = st;
    for(int i = st; i <= ed; i++){
        if(mx < player[playing_order[i]].weight){
            mx = player[playing_order[i]].weight;
            key = i;
        }
        player[playing_order[i]].order = ranks + 1;
    }
    return key;
}

int main() {

    int n, k, countRest, new_rest, j, mx;
    int ranks;

    while(scanf("%d%d", &n, &k) != EOF) {

        //input
        for (int i = 0; i < n; i++) {
            scanf("%d", &player[i].weight);
            player[i].order = i;
        }
        for(int i = 0; i < n; i++) {
            scanf("%d", &playing_order[i]);
        }

        countRest = n; //记录每次选出的人数(剩余数)
        while(countRest > 1){ //循环筛选,直到剩一个

            new_rest = 0;  //记录这一轮选出的人数
            if(countRest % k == 0)
                ranks = countRest / k; //防止整分的情况
            else
                ranks = countRest / k + 1;

            //筛选
            for(j = 0; j + k < countRest; j += k) {
                mx = getMax(j, j + k - 1, ranks); //查找的同时把名次记录了
                rest_order[new_rest++] = playing_order[mx];  //选出的player下标保存在新队列

            }
            mx = getMax(j, countRest - 1, ranks);  //处理最后尾部数据
            rest_order[new_rest++] = playing_order[mx];

            //剩余Mice的序号,转移
            for (int l = 0; l < countRest; l++)
                playing_order[l] = rest_order[l];

            //一轮筛选结束
            countRest = new_rest;  //new_test == ranks
        }//while
        player[playing_order[0]].order = 1;  //最后剩余的为第一名

        for (int i = 0; i < n - 1; i++)
            printf("%d ", player[i].order);
        printf("%d\n", player[n - 1].order);

    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_26398495/article/details/81135624
今日推荐