2021秋季《数据结构》_EOJ 1057. 排名汇总

题目

程序设计能力实训是华东师范大学计软院让学生非常头痛的一门课程,课程考试旨在通过统一组织的在线考试及自动评测方法客观地评判考生的算法设计与程序设计实现能力,每次考试会有多个考场同时进行考试,假设每个考场会在考试结束后产生一份学生成绩,之后将各个考场的成绩汇总为一份总的成绩单,现在请你对这张总的成绩单进行排名。
在这里插入图片描述

思路

实训,我的痛苦面具
需要注意的是,同分的同学排名一致。虽然输出时学号为第二关键字,但在赋排名时不能简单+1。
需要考虑遍历每个考场中的学生时数组越界的问题。

方法1

简单的做法是用库函数sort,由于二维数组行分布并不均匀,处理起来有点麻烦(其实是太菜处理不好),所以将排好序的二维数组拷贝进一个一维数组重新排序。

方法2

由于题目要求,已经排好了各小数组的顺序,考虑使用归并排序。

代码

方法1

#include<bits/stdc++.h>
using namespace std;

struct student
{
	long long numStu;  // 学号
	int rankAll;  // 所有人中的排名
	int numTest;  // 考场号
	int rankLoc;  // 本考场中的排名
	int score = -1;  // 分数
};

bool cmp1(student a, student b)
{
	if (a.score != b.score)
		return a.score > b.score;
	else return a.numStu < b.numStu;
}

int main()
{
	int n; cin >> n;
	int allStu = 0;
	student** a = new student * [n + 1];
	int* tmpNumTest = new int[n + 1];
	for (int i = 1; i <= n; i++)
		// 考场号为i
	{
		int numTest; cin >> numTest;
		allStu += numTest;
		a[i] = new student[numTest];
		tmpNumTest[i] = numTest;
		for (int j = 0; j < numTest; j++)
		{
			a[i][j].numTest = i;
			long long numStu;
			int score;
			cin >> numStu >> score;
			a[i][j].numStu = numStu;
			a[i][j].score = score;
		}
		sort(a[i], a[i] + numTest, cmp1);
		//for (int j = 0; j < numTest; j++)
		//{
		//	a[i][j].rankLoc = j + 1;
		//}
		a[i][0].rankLoc = 1;
		int kk = 1;
		int step = 1;
		while (kk<numTest)
		{
			if (a[i][kk].score == a[i][kk - 1].score)
			{
				a[i][kk].rankLoc = a[i][kk - 1].rankLoc;
				kk++;
				step++;
			}
			else
			{
				a[i][kk].rankLoc = a[i][kk - 1].rankLoc + step;
				kk++;
				step = 1;
			}
			
		}

		//cout << "*************" << endl;
		//for (int j = 0; j < numTest; j++)
		//{
		//	cout << a[i][j].numStu << ' ' << a[i][j].numTest << ' '<< a[i][j].rankLoc << endl;
		//}
	}
	cout << allStu << endl;
	student* res = new student[allStu + 1];
	int idxRes = 0;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 0; j < tmpNumTest[i] && a[i][j].score != -1; j++)
		{
			res[idxRes].numStu = a[i][j].numStu;
			res[idxRes].numTest = a[i][j].numTest;
			res[idxRes].rankLoc = a[i][j].rankLoc;
			res[idxRes].score = a[i][j].score;
			idxRes++;
		}
	}
	sort(res, res + allStu, cmp1);
	res[0].rankAll = 1;
	int ii = 1;
	int sstep = 1;
	while (ii < allStu)
	{
		if (res[ii].score == res[ii - 1].score)
		{
			res[ii].rankAll = res[ii - 1].rankAll;
			sstep++;
		}
		else
		{
			res[ii].rankAll = res[ii - 1].rankAll + sstep;
			sstep = 1;
		}
		ii++;
	}
	for (int i = 0; i < allStu; i++)
	{
		cout << res[i].numStu << ' ' << res[i].rankAll << ' ' << res[i].numTest << ' ' << res[i].rankLoc << endl;
	}
	return 0;
}

方法2

#include<bits/stdc++.h>
using namespace std;
#define K 300

struct student
{
	long long numStu;  // 学号
	int rankAll;  // 所有人中的排名
	int numTest;  // 考场号
	int rankLoc;  // 本考场中的排名
	int score = -1;  // 分数
};

bool cmp1(student a, student b)
{
	if (a.score != b.score)
		return a.score > b.score;
	else return a.numStu < b.numStu;
}

int main()
{
	int n; cin >> n;
	int allStu = 0;
	student** a = new student * [n + 1];
	int* tmpNumTest = new int[n + 1];
	for (int i = 1; i <= n; i++)
		// 考场号为i
	{
		int numTest; cin >> numTest;
		allStu += numTest;
		a[i] = new student[K];
		tmpNumTest[i] = numTest;
		for (int j = 0; j < numTest; j++)
		{
			a[i][j].numTest = i;
			long long numStu;
			int score;
			cin >> numStu >> score;
			a[i][j].numStu = numStu;
			a[i][j].score = score;
		}
		sort(a[i], a[i] + numTest, cmp1);

		a[i][0].rankLoc = 1;
		int kk = 1;
		int step = 1;
		while (kk < numTest)
		{
			if (a[i][kk].score == a[i][kk - 1].score)
			{
				a[i][kk].rankLoc = a[i][kk - 1].rankLoc;
				kk++;
				step++;
			}
			else
			{
				a[i][kk].rankLoc = a[i][kk - 1].rankLoc + step;
				kk++;
				step = 1;
			}

		}

		//cout << "*************" << endl;
		//for (int j = 0; j < numTest; j++)
		//{
		//	cout << a[i][j].numStu << ' ' << a[i][j].numTest << ' '<< a[i][j].rankLoc << ' ' << a[i][j].score<<endl;
		//}
	}
	cout << allStu << endl;
	student* res = new student[allStu + 1];
	int* head = new int[n+1];
	memset(head, 0, sizeof(int) * (n + 1));
	int idxRes = 0;
	//int maxScore = 0;
	//int maxIdx = 1;
	while (idxRes<allStu)
	{
		int maxScore = 0;
		int maxIdx = 1;
		for (int i = 1; i <= n; i++)
		// 遍历每一个考场
		{
			if (head[i] >= tmpNumTest[i]) continue;  // 考虑数组越界问题
			if (a[i][head[i]].score>maxScore || (a[i][head[i]].score==maxScore && a[i][head[i]].numStu<=a[maxIdx][head[maxIdx]].numStu))
			{
				maxScore = a[i][head[i]].score;
				maxIdx = i;
			}
		}
		res[idxRes].score = maxScore;
		res[idxRes].numStu = a[maxIdx][head[maxIdx]].numStu;
		res[idxRes].numTest = a[maxIdx][head[maxIdx]].numTest;
		res[idxRes].rankLoc = a[maxIdx][head[maxIdx]].rankLoc;
		head[maxIdx]++;
		idxRes++;
		maxIdx= maxIdx==1?maxIdx+1:maxIdx-1;
	}
	res[0].rankAll = 1;
	int ii = 1;
	int sstep = 1;
	while (ii < allStu)
	{
		if (res[ii].score == res[ii - 1].score)
		{
			res[ii].rankAll = res[ii - 1].rankAll;
			ii++;
			sstep++;
		}
		else
		{
			res[ii].rankAll = res[ii - 1].rankAll + sstep;
			ii++;
			sstep = 1;
		}

	}

	for (int i = 0; i < allStu; i++)
	{
		cout << res[i].numStu << ' ' <<res[i].rankAll<<' ' << res[i].numTest << ' ' << res[i].rankLoc << endl;
	}

	


	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值