中国大学生计算机设计大赛是我国高校面向本科生的计算机应用设计大赛,大赛旨在激发学生学习计算机知识和技能的兴趣与潜能,提高学生运用信息技术解决实际问题的综合能力。通过大赛这种计算机教学实践形式,可展示师生的教与学成果,最终以赛促学,以赛促教,以赛促创。该赛事在历届学生中影响力较大,参与者众多,请结合2021届省赛参赛的数据,借助数据结构课程所学的相关知识,通过对数据的处理和分析,全面了解赛事组织及管理的体系,以及数据结构设计及数据处理在信息管理系统中应用的重要性。赛事相关数据存储在文本文件和excel文件中,相应的文件信息说明如表1所示。
问题描述
要求协助中国大学生计算机设计大赛江苏省组委会,设计一款赛事管理系统,实现赛务相关的数据管理及信息服务,该系统能够为省级赛事管理解决以下问题:
(1)从team.txt中读取参赛队伍的基本信息,能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师);包括增加、删除、修改参赛队伍的信息。
(2)实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL
(3)能够提供按参赛学校查询参赛团队,根据提示输入参赛学校名称,若查找成功,输出该学校参赛的所有团队的基本信息,输出的参赛团队需有序输出(按参赛队编号)。(排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。)
(4)为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到17个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。
(5)赛事系统为参赛者提供赛地的校园导游程序。为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于12个目标地的导航。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供图中任意目标地(建筑物)的问路查询,即查询任意两个目的地(建筑物)之间的一条最短的简单路径。
1.1赛事信息管理
从team.txt中读取参赛队伍的基本信息,设计合适的数据结构存储。可以使用一个队伍类(Team)来存储参赛队伍的基本信息,包括队伍编号、参赛作品名称、参赛学校、赛事类别、参赛者和初赛成绩等信息。
实现对参赛队伍的增加、修改和浏览功能。可以设计一个队伍管理类(TeamManager),包含添加队伍、修改队伍信息和浏览队伍信息等方法。
这个任务涉及到了数据的输入、处理和管理,具体可以被分解为以下步骤:
1. 读取数据:从一个名为"team.txt"的文件中读取数据。这个文件包含了各个参赛队的基本信息,包括参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师。首先,需要编写一个能够处理这个文件的程序,并把信息读取到适当的数据结构中。
2. 数据管理:一旦信息被读入,就需要进行数据管理。来存储和检索这些信息。数据管理应该包括增加新的队伍,删除已有的队伍,以及修改队伍信息的能力。
3. 赛事类别:赛事类别有不同的项,这可能意味着需要一个列表来存储这些类别,并且可能需要对应的功能来处理与这些类别有关的信息。
1算法分析
定义比赛管理类
class EventManagementSystem {
private:
map<string, Team> teams; // 使用map存储参赛队伍,以队伍编号作为key
vector<double> searchLengths; // 存储每次查询的查找长度
public:
void readTeamInfoFromFile(string filename) {
ifstream file(filename);
if (!file) {
cout << "Failed to open file: " << filename << endl;
return;
}
string line;
while (getline(file, line)) {
Team team;
team.teamId = line.substr(0, 4);
team.teamName = line.substr(4, 20);
team.school = line.substr(24, 20);
team.category = line.substr(44, 20);
teams[team.teamId] = team;
}
file.close();
}
添加
void addTeam() {
Team team;
cout << "Enter team ID: ";
cin >> team.teamId;
cout << "Enter team name: ";
cin >> team.teamName;
cout << "Enter school: ";
cin >> team.school;
cout << "Enter category: ";
cin >> team.category;
teams[team.teamId] = team;
}
更新队伍信息
void updateTeam() {
string teamId;
cout << "Enter team ID to update: ";
cin >> teamId;
if (teams.find(teamId) != teams.end()) {
Team& team = teams[teamId];
cout << "Enter new team name: ";
cin >> team.teamName;
cout << "Enter new school: ";
cin >> team.school;
cout << "Enter new category: ";
cin >> team.category;
}
else {
cout << "Team not found!" << endl;
}
}
2 基于二叉排序树的查找
实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。请输出ASL的计算表达式和结果值。
2.1 问题分析
问题的步骤可以被分解为以下几个部分:
创建二叉排序树:根据读入的数据,创建一个二叉排序树,使每个节点都包含一个参赛队的信息,节点的键是参赛队编号。
进行查找:当接收到一个参赛队编号输入时,从二叉排序树中查找这个编号。这可以通过比较输入的编号和树的节点来实现。如果输入的编号小于某个节点,那么就在这个节点的左子树中继续查找;如果输入的编号大于某个节点,那么就在这个节点的右子树中继续查找;如果输入的编号等于某个节点,那么查找成功。
处理查找结果:如果查找成功,输出这个节点包含的参赛队的信息,并计算和输出平均查找长度ASL。
2.2算法分析
分配成绩
void assignScore() {
for (auto& pair : teams) {
Team& team = pair.second;
team.score = 60 + (rand() % 41); // 分配60~100之间的随机分数
}
}
3决赛现场模拟
3.1算法分析
这里我选择希尔排序
// 将参赛队伍按照分数降序排列
for (const auto& pair : teams) {
finalTeams.push_back(pair.second);
}
sort(finalTeams.begin(), finalTeams.end(), [](const Team& a, const Team& b) {
return a.score > b.score;
});
4决赛地图导览
为参赛者提供决赛主办地的各种路径导航的查询服务,以我校长山校区提供比赛场地为例,为参赛者提供不少于12个目标地的导航。为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供图中任意目标地(建筑物)的问路查询。
4.1代码分析
class Map {
public:
unordered_map<string, Location*> locations;
void addLocation(string name) {
Location* location = new Location(name);
locations[name] = location;
}
void addConnection(string from, string to) {
locations[from]->addConnection(to);
locations[to]->addConnection(from);
}
void printConnections(string location) {
cout << "Connections for " << location << ":" << endl;
for (string connection : locations[location]->connections) {
cout << connection << endl;
}
}
};