P8342 [COCI2021-2022#6] Med 题解
P8342 [COCI2021-2022#6] Med 题解
蒟蒻题解,不喜勿喷
题目传送门
step 1 题目理解
简单地说,这个题目就是一个排序的运用。
在最后一轮比赛开始前,输出每个养蜂人的最佳排名以及最差排名。
step 2 解题思路
要求出最佳排名和最差排名,就要首先了解对于一位养蜂人的最佳情况和最差情况分别是什么。
我们可以自行带入一下,如果我是一名养蜂人,在最后一场比赛开始前,最好的情况就是最后一场比赛我自己一个人得满分,其他人都零分,而最差情况自然就是我自己一人得零分,其他人都得满分。
根据这两种情况,我定义了两个数组,maxbi 以及 minbi,用来存放第i个养蜂人的最佳得分情况和最差得分情况(其实在做完此题后才发现,这样有点画蛇添足了,但是这样做更加容易理解 至少我觉得是的)。
然后就是排序阶段了,我这里使用的 c++ 函数库自带的 sort() 函数进行结构体类型变量的排序。
结构体变量由得分和养蜂人的编号组成。排序阶段,外层是一个 i 从 1 到 n 的大循环,表示我们要求的养蜂人的编号。在循环内部,分为两个部分,分别计算最佳排名和最差排名。最佳排名部分,将结构体的下标为 i 的元素的得分设为 maxbi 其余的元素都将得分设为 minbi ,最差部分 maxbi 和 minbi 恰好相反。在排序后,找到养蜂人编号为 i 的元素,直接输出该元素的下标即可。
这样,该题的核心部分就完成了
在排序时有几点需要注意:
1.结构体变量的组成
2.字典序的比较
3.比较时需要自定义cmp比较函数
结构体:
struct node{
int num;//得分情况
int id;//养蜂人编号
};
字典序比较:
bool jdg(string a,string b){
int a_len=a.size(),b_len=b.size(),i=0,j=0;
while(a_len!=0&&b_len!=0){
if(a[i++]==b[j++]){a_len--;b_len--;continue;}
return a[i-1]<b[i-1];
//如果两字母相等,则继续比较,否则直接返回 a[i-1]<b[i-1] 的值
}
if(a_len==0) return 0;
return 1;
//如果其中a名字已完全比较完,则返回0,否则返回1
}
cmp比较函数:
bool cmp(node a,node b){
if(a.num==b.num) return jdg(name[a.id],name[b.id]);
//若两得分相等,则比较名字的字典序
return a.num>b.num;
//若两得分不相等,则返回 a.num>b.num 的值
}
step 3 AC代码
AC代码如下,悉数奉上
因为本人太蒻,这道题代码比较长,没有做相应的一些优化,各位通过该题的大佬勿喷
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
string name[N];
int maxbi[N],minbi[N],n,x;
//maxbi数组存放最大得分,minbi数组存放最小得分
struct node{//进行结构体排序的结构体
int num;//得分情况
int id;//养蜂人编号
};
bool jdg(string a,string b){//判断名字的字典序
int a_len=a.size(),b_len=b.size(),i=0,j=0;
while(a_len!=0&&b_len!=0){
if(a[i++]==b[j++]){a_len--;b_len--;continue;}
return a[i-1]<b[i-1];
}
if(a_len==0) return 0;
return 1;
}
bool cmp(node a,node b){//比较函数
if(a.num==b.num) return jdg(name[a.id],name[b.id]);
return a.num>b.num;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){//输入部分
cin>>name[i];
for(int j=1;j<=5;j++){
cin>>x;
minbi[i] += x;
}
maxbi[i] = minbi[i] + 500;
}
node nst[n+1];
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){//排序前处理
if(j==i) nst[j].num=maxbi[j];
else nst[j].num=minbi[j];
nst[j].id = j;
}
sort(nst+1,nst+n+1,cmp);
for(int j=1;j<=n;j++) if(nst[j].id==i) cout<<j<<' ';
//以上为最佳情况计算和输出
for(int j=1;j<=n;j++){//排序前处理
if(j!=i) nst[j].num=maxbi[j];
else nst[j].num=minbi[j];
nst[j].id = j;
}
sort(nst+1,nst+n+1,cmp);
for(int j=1;j<=n;j++) if(nst[j].id==i) cout<<j<<endl;
//以上为最差情况计算和输出
}
return 0;
}