解题过程的小记录,如有错误欢迎指出。
难度:五星(题目读了好几遍也没读懂,不过看了解析后决定自己就算看懂题目可能也做不出来orz)
题目分析
第一行给出的是总共的老鼠数和每一组老鼠的数量
第二行给出的是每只老鼠的数量
第三行给出的是每只老鼠的编号
按给出的顺序分组,选出每一组中体重最大的老鼠晋级下一轮,下一轮再次进行分组,一直进行循环,知道找到第一名(第一名一定是所有老鼠中最重的,但第二名不一定是所有老鼠中第二重的)
注意点
- 第三行给出的是老鼠的编号
- 老鼠按照给出的老鼠编号,从左到右进行分组(给出编号是为了,按照编号去第二号找对应的重量)
我的解题过程
思路
- 把第二行的信息存入老鼠数组(是一个结构体数组,里面包含了体重和排名)
- 把第三行信息存入队列,从队首到队尾是按顺序成组比较的
- 设置变量保存当前剩余的需要比较的老鼠数和成组数
- 当队列不为1时(说明最大的老鼠数还没有找出来,还可以进行分组),进行分组找出每一组中体重最大的老鼠数,插入队列尾
- 进行一轮比赛就可以为所有参加这一轮比赛的老鼠进行排名的赋值,无论这一轮是否晋级,参加了这一轮就说明上一轮晋级了,所以可以赋值为group+1
- 当队列中只有一个老鼠编号时,为其排名赋值为1
- 按照编号顺序进行输出排名
bug
无从谈bug,完全写不来,代码是看着晴神的代码copy的,按照自己的代码风格略做了修改
代码
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
struct mouse {
int weight, rank;
};
int main()
{
int np, ng;//参加比赛人数和一组拥有的最多人数
scanf("%d %d\n", &np, &ng);
vector<mouse> mice(np);
for (int i = 0; i < np; i++) {
scanf("%d", &mice[i].weight);
}
queue<int> q;//定义一个队列
int order;
for (int i = 0; i < np; i++) {
scanf("%d", &order);//题目中给出的老鼠的标号
q.push(order);//按顺序把老鼠们的标号入队
}
int left = np, group;//left为当前轮的比赛总老鼠数,group为组数
while (q.size() != 1) {
//计算group,即当前轮分为几组进行比赛
if (left%ng == 0) group = left / ng;//最后一组也人数刚好
else group = left / ng + 1;//最后一组人数不足,用除法会少掉一组
//枚举每一组,选出改组老鼠中质量最大的
for (int i = 0; i < group; i++) {
int k = q.front();//k存放改组质量最大的老鼠编号
for (int j = 0; j < ng; j++) {
//在最后一组老鼠不足ng时(凑不够一组时),退出循环
if (i*ng + j >= left) break;
int front = q.front();//队首老鼠编号
if (mice[front].weight > mice[k].weight) {
k = front;//找出质量最大的老鼠的编号
}
mice[front].rank = group + 1;//该轮老鼠排名为group+1
q.pop();//把队首的这只老鼠出队
}
q.push(k);//把找出的质量最大的老鼠的编号插入队尾
}
left = group;//剩下的老鼠数为每一组的晋级老鼠数量,共有group个组,所以有group只老鼠晋级
}
mice[q.front()].rank = 1;//当队列中只有1只老鼠时,令其排名为1
//输出所有老鼠的信息
for (int i = 0; i < np; i++) {
if (i != 0) printf(" ");
printf("%d", mice[i].rank);
}
return 0;
}
dalao的代码
全部代码因版权原因不放出来,大家可以自行去柳神博客购买或者参考晴神的上机笔记~
借鉴点
本题看本篇解析代码即可,因为代码就是copy大佬的,如果看不懂可以去看晴神的分析