PAT(甲级)1056 Mice and Rice (25point(s))

题目

题目链接

思路

题意是给你每个老鼠的重量,请你根据老鼠的重量为他们排名;
但排名并不是通过一场比赛决定,而是通过小组赛的方式,意味着重的老鼠不一定排名靠前;
小组赛机制是每轮将剩余选手分成小组,每个小组选一名选手晋级下一轮;
首先来思考如何得到每个选手的排名,因为每轮失败的选手排名一样,所以每轮晋级的选手数 + 1 就是本轮失败选手的排名;
我们可以用队列进行模拟,队列中存放的是选手的ID,在开始每一轮比赛前,先获取队列中元素的个数,也就是本轮参赛选手的人数,然后将本轮参赛选手依次出队,出队的过程中为那些淘汰的人写入排名,那些晋级的人排名未知,需要在下一轮才能得到;
注意到每个小组胜利的人需要再次入队,进行下一轮比赛;

代码
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
const int maxn = 1010;
int NP, NG, temp;
vector<int> w(maxn), rankk(maxn);
queue<int> qu;

int main()
{
     //读入组数
    scanf("%d%d", &NP, &NG);
    for(int i = 0; i < NP; i ++) scanf("%d", &w[i]);
    //把每一个人都放进队列中
    for(int i = 0; i < NP; i ++) {
          scanf("%d", &temp);
          qu.push(temp);
    }
    int pre = -1, cur;//pre代表每个小组晋级人的下标
    while(qu.size() > 1){
          int cnt = qu.size();//cnt代表这轮一共有多少人
          int r = 0;
          //r代表这局淘汰的人的排名,如果可以整除,就代表有cnt / NG 个小组,不可以整除就代表有cnt / NG + 1个小组
          if(cnt % NG == 0) r = cnt / NG + 1;
          else r = cnt / NG + 2;
          //将这cnt个人出队
          for(int i = 1; i <= cnt; i ++){
               cur = qu.front();
               qu.pop();
               //pre == -1代表这个人是小组的第一人,自然不需要比较
               if(pre == -1) pre = cur;
               //如果当前选手的重量大于小组目前重量最大值,更新pre
               else if(w[cur] > w[pre]){
                    rankk[pre] = r;
                    pre = cur;
               }
               else if(w[cur] < w[pre]){
                    rankk[cur] = r;
               }
               //当每个小组比赛结束后,需要将胜利人的ID放入队列,进行下一轮比赛
               if(i % NG == 0 || i == cnt){
                    qu.push(pre);
                    if(qu.size() != 1) pre = -1;
               }
          }
    }
    rankk[pre] = 1;
    for(int i = 0; i < NP; i ++){
	      printf("%d", rankk[i]);
	      if(i != NP - 1) printf(" ");
    } 
    //system("pause");
    return 0;
}

吐槽:这道题想了好长时间啊,WA

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值