ZISUOJ 一道抽象的结构体排序题

文章讲述了作者在解决编程题目中,如何使用C11的lambda函数对选手成绩进行排序,先去除最高和最低分,然后根据平均分和最低分的得分进行复杂排序,最后正确调整了输出循环条件,解决了所有错误并成功通过测试。
摘要由CSDN通过智能技术生成

说明:

        这个题纯纯抽象,条件太多了,错了三次第四次提交的时候才对。这里顺带介绍一下C11的新特性lambda函数,之前有学习过python,对lambda还是比较熟悉的。

        lambda函数优点:1.它能够在需要使用的时候定义,而无需跳出当前函数,在函数外重新定义一个函数或者struct。2.使代码看起来简洁。

题目:

2675: 去最高最低分后成绩排序

 做题过程复现:

分析:

        开结构体数组存放名字和n个评委的打分以及后续会使用到的去掉最高最低分的平均值还有最低分的下标。读入后一通操作计算得到相应的平均分和最低分的下标。然后sort()排序,排序规则我这里直接使用了lambda函数写。排序好后直接输出。看着思路没什么问题,提交试试。

代码:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
//using PII = pair<int,int>;
//const int N = 1e4+5;
struct player{
	string name;
	int score[15];
	int minidx;
	double avg;
}a[35];
void solve(){
	int n;cin >> n;
	int idx = 1;
	while(cin >> a[idx].name){
		for(int i = 1;i<=n;i++) cin >> a[idx].score[i];
		idx++;
	}
	for(int i = 1;i<idx;i++){
		double avg = 0;
		int maxn = INT_MIN,maxidx,minn = INT_MAX,minidx;
		for(int j = 1;j<=n;j++){
			if(a[i].score[j]>maxn){
				maxn = a[i].score[j];
				maxidx = j;
			}
			if(a[i].score[j]<minn){
				minn = a[i].score[j];
				minidx = j;
			}
		}
		a[i].minidx=minidx;
		for(int j = 1;j<=n;j++){
			if(j==maxidx||j==minidx) continue;
			avg+=a[i].score[j];
		}
		avg/=(n-2);
		a[i].avg=avg;
	}
	sort(a+1,a+idx,[](player a1,player a2){if(a1.avg!=a2.avg) return a1.avg>a2.avg;else if(a1.avg==a2.avg&&a1.score[a1.minidx]!=a2.score[a2.minidx]) return a1.score[a1.minidx]>a2.score[a2.minidx];else return a1.name<a2.name;});
	for(int i = 1;i<=n;i++){
		cout << i << ". ";
		cout << a[i].name << ' ';
		cout << fixed << setprecision(2) << a[i].avg;
		cout << endl;
	}
}
int main(){
	//2675: 去最高最低分后成绩排序
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t = 1;
	//cin >> t;
	while(t--) solve();
	return 0;
}

报错了(答案错误50%):

        观察报错信息和后台测试点对比发现是输出的循环写的有问题,输出的for()循环的结束条件写错了,修改一下再提交:

代码:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
//using PII = pair<int,int>;
//const int N = 1e4+5;
struct player{
	string name;
	int score[15];
	int minidx;
	double avg;
}a[35];
void solve(){
	int n;cin >> n;
	int idx = 1;
	while(cin >> a[idx].name){
		for(int i = 1;i<=n;i++) cin >> a[idx].score[i];
		idx++;
	}
	for(int i = 1;i<idx;i++){
		double avg = 0;
		int maxn = INT_MIN,maxidx,minn = INT_MAX,minidx;
		for(int j = 1;j<=n;j++){
			if(a[i].score[j]>maxn){
				maxn = a[i].score[j];
				maxidx = j;
			}
			if(a[i].score[j]<minn){
				minn = a[i].score[j];
				minidx = j;
			}
		}
		a[i].minidx=minidx;
		for(int j = 1;j<=n;j++){
			if(j==maxidx||j==minidx) continue;
			avg+=a[i].score[j];
		}
		avg/=(n-2);
		a[i].avg=avg;
	}
	sort(a+1,a+idx,[](player a1,player a2){if(a1.avg!=a2.avg) return a1.avg>a2.avg;else if(a1.avg==a2.avg&&a1.score[a1.minidx]!=a2.score[a2.minidx]) return a1.score[a1.minidx]>a2.score[a2.minidx];else return a1.name<a2.name;});
	for(int i = 1;i<idx;i++){
		cout << i << ". ";
		cout << a[i].name << ' ';
		cout << fixed << setprecision(2) << a[i].avg;
		cout << endl;
	}
}
int main(){
	//2675: 去最高最低分后成绩排序
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t = 1;
	//cin >> t;
	while(t--) solve();
	return 0;
}

又报错了(答案错误12%):

 

        观察报错信息发现原来平均分相同,排名次时也是同名的,而不是简单地输出排序后的下标。修改一下代码再次提交。

代码:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
//using PII = pair<int,int>;
//const int N = 1e4+5;
struct player{
	string name;
	int score[15];
	int minidx;
	double avg;
}a[35];
void solve(){
	int n;cin >> n;
	int idx = 1;
	while(cin >> a[idx].name){
		for(int i = 1;i<=n;i++) cin >> a[idx].score[i];
		idx++;
	}
	for(int i = 1;i<idx;i++){
		double avg = 0;
		int maxn = INT_MIN,maxidx,minn = INT_MAX,minidx;
		for(int j = 1;j<=n;j++){
			if(a[i].score[j]>maxn){
				maxn = a[i].score[j];
				maxidx = j;
			}
			if(a[i].score[j]<minn){
				minn = a[i].score[j];
				minidx = j;
			}
		}
		a[i].minidx=minidx;
		for(int j = 1;j<=n;j++){
			if(j==maxidx||j==minidx) continue;
			avg+=a[i].score[j];
		}
		avg/=(n-2);
		a[i].avg=avg;
	}
	sort(a+1,a+idx,[](player a1,player a2){if(a1.avg!=a2.avg) return a1.avg>a2.avg;else if(a1.avg==a2.avg&&a1.score[a1.minidx]!=a2.score[a2.minidx]) return a1.score[a1.minidx]>a2.score[a2.minidx];else return a1.name<a2.name;});
	int rank = 1;
	for(int i = 1;i<idx;i++){
		cout << rank << ". ";
		cout << a[i].name << ' ';
		cout << fixed << setprecision(2) << a[i].avg;
		cout << endl;
		if(i<idx-1&&a[i].avg==a[i+1].avg) continue;
		else rank++;
	}
}
int main(){
	//2675: 去最高最低分后成绩排序
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t = 1;
	//cin >> t;
	while(t--) solve();
	return 0;
}

又双叒叕错了(答案错误37%):

 

观察后台测试点发现:

        只有在平均分相同且最低分相同时才会同名次,最后一次修改代码提交。

代码:

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
//using PII = pair<int,int>;
//const int N = 1e4+5;
struct player{
	string name;
	int score[15];
	int minidx;
	double avg;
}a[35];
void solve(){
	int n;cin >> n;
	int idx = 1;
	while(cin >> a[idx].name){
		for(int i = 1;i<=n;i++) cin >> a[idx].score[i];
		idx++;
	}
	for(int i = 1;i<idx;i++){
		double avg = 0;
		int maxn = INT_MIN,maxidx,minn = INT_MAX,minidx;
		for(int j = 1;j<=n;j++){
			if(a[i].score[j]>maxn){
				maxn = a[i].score[j];
				maxidx = j;
			}
			if(a[i].score[j]<minn){
				minn = a[i].score[j];
				minidx = j;
			}
		}
		a[i].minidx=minidx;
		for(int j = 1;j<=n;j++){
			if(j==maxidx||j==minidx) continue;
			avg+=a[i].score[j];
		}
		avg/=(n-2);
		a[i].avg=avg;
	}
	sort(a+1,a+idx,[](player a1,player a2){if(a1.avg!=a2.avg) return a1.avg>a2.avg;else if(a1.avg==a2.avg&&a1.score[a1.minidx]!=a2.score[a2.minidx]) return a1.score[a1.minidx]>a2.score[a2.minidx];else return a1.name<a2.name;});
	int rank = 1;
	for(int i = 1;i<idx;i++){
		cout << rank << ". ";
		cout << a[i].name << ' ';
		cout << fixed << setprecision(2) << a[i].avg;
		cout << endl;
		if(i<idx-1&&a[i].avg==a[i+1].avg&&a[i].score[a[i].minidx]==a[i+1].score[a[i+1].minidx]) continue;
		else rank++;
	}
}
int main(){
	//2675: 去最高最低分后成绩排序
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t = 1;
	//cin >> t;
	while(t--) solve();
	return 0;
}

过啦!

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Beau_Will

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值