【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程序(更简)
/**********************************
*@ID: 3stone
*@ACM: PAT.A1056 Mice and Rice
*@Time: 19/2/13
*@IDE: VScode 2018 + clang++ 
***********************************/
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>

using namespace std;

const int maxn = 1010;

struct Player {
	int weight, ranks;
}player[maxn];  //玩家
int order[maxn]; //游戏位置

int getMax(int st, int ed, int ranks) {
	int key = st, maxNum = -1;
	for(int i = st; i <= ed; i++) {
		if(maxNum < player[order[i]].weight){
			key = i;
			maxNum = player[order[i]].weight;
		}
		player[order[i]].ranks = ranks + 1; //记录排名
	}
	return key;
}

int main() {
	int Np, Ng;
	scanf("%d%d", &Np, &Ng);

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

	int count, restNum = Np;

	while(restNum > 1) {
		if(restNum % Ng == 0) count = restNum / Ng; //分组数
		else count = restNum / Ng + 1;

		//按组筛选
		int cur = 0, i = 0, key;
		for(i = 0; i + Ng < restNum; i += Ng) {
			key = getMax(i, i + Ng - 1, count); //返回order的下标
			order[cur++] = order[key];
		}
		//处理最后一组
		if(i < Np) {
			key = getMax(i, restNum - 1, count);
			order[cur++] = order[key];
		}
		
		restNum = cur; //更新剩余人数
	
	}//while
	player[order[0]].ranks = 1;

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

	system("pause");
	return 0;
}


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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值