题目链接
题目分析
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;
}