中国大学生计算机设计大赛省级赛事管理系统
中国大学生计算机设计大赛是我国高校面向本科生的计算机应用设计大赛,大赛旨在激发学生学习计算机知识和技能的兴趣与潜能,提高学生运用信息技术解决实际问题的综合能力。通过大赛这种计算机教学实践形式,可展示师生的教与学成果,最终以赛促学,以赛促教,以赛促创。该赛事在历届学生中影响力较大,参与者众多,请结合2021届省赛参赛的数据,借助数据结构课程所学的相关知识,通过对数据的处理和分析,全面了解赛事组织及管理的体系,以及数据结构设计及数据处理在信息管理系统中应用的重要性。赛事相关数据存储在文本文件和excel文件中,相应的文件信息说明如表1所示。其中,各个文件中不同的数据项之间均使用#分隔,图1中给出了文件team.txt中参赛信息的对应数据示例。
【问题描述】
本次课程设计要求协助中国大学生计算机设计大赛江苏省组委会,设计一款赛事管理系统,实现赛务相关的数据管理及信息服务,该系统能够为省级赛事管理解决以下问题:
(1)能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项(参见大赛官网jsjds.blcu.edu.cn);包括增加、删除、修改参赛队伍的信息。
(2)从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。
(3)能够提供按参赛学校查询参赛团队(或根据赛事类别查询参赛团队),即,根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。(排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。)
(4)为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。(模拟时,要能直观展示叫号顺序与进场秩序一致)
(5)赛事系统为参赛者提供赛地的校园导游程序,为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于10个目标地的导航。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供任意两个目标地(建筑物)的导航查询,即查询任意两个目的地(建筑物)之间的一条最短路径。
【设计要求】
1)赛事数据要求存入文件(txt或excel)并能读入查询;
2)赛地目的地查询,需提供目的地(建筑物)名称、代号、简介、两地之间路径长度等信息;
3)输入数据形式和范围:赛事相关数据可从键盘输入,或自文件导入。
4)界面要求:交互设计要合理,每个功能可以设计菜单,用户根据提示,完成相关功能的要求。
问题一
从team.txt中读取参赛队伍的基本信息,能够管理各参赛队的基本信息,包括增加、删除、修改参赛队伍的信息。
先定义一个名为 Team 的结构体,它包含了 7 个成员变量:
// 参赛队伍信息结构体
struct Team {
string number; // 参赛队编号
string name; // 参赛作品名称
string school; // 参赛学校
string category; // 赛事类别
string participant; // 参赛者
string teacher; // 指导教师
int DefenseTime; // 答辩时间
};
下面继续定义一个函数read_teams_from_file,它的作用是从一个指定的文件中读取参赛队伍的信息,并将这些信息存储到一个vector容器中。
// 从文件中读取参赛队伍信息的函数
vector<Team> read_teams_from_file(const string &filename) {}
下面继续定义一个函数 write_teams_to_file,该函数的作用是将参赛队伍信息写入到指定的文件中。
// 将参赛队伍信息写入文件的函数
void write_teams_to_file(const string& filename, const vector<Team>& teams) {}
继续定义一个函数 add_team,该函数的作用是向一个 vector 类型的参赛队伍信息 teams 中添加一支新的参赛队伍。
// 添加参赛队伍信息的函数
void add_team(vector<Team>& teams) {}
下面继续定义一个函数 modify_team,该函数的作用是修改一个 vector 类型的参赛队伍信息 teams 中的一支参赛队伍的信息。
// 修改参赛队伍信息的函数
void modify_team(vector<Team>& teams) {}
最后定义一个delete_team函数,作用是从一个存储参赛队伍信息的 vector 中删除指定编号的参赛队伍。
// 删除参赛队伍信息的函数
void delete_team(vector<Team>& teams) {}
实验结果:
问题二
实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息。同时,输出查找成功时的平均查找长度ASL。
定义一个二叉排序树节点的结构体 BSTNode。
// 定义二叉排序树节点结构体
struct BSTNode {
Team data; // 数据域
BSTNode* left, *right; // 左右子树指针
BSTNode(Team team) :
data(team),
left(nullptr),
right(nullptr) {} // 构造函数
};
接着设计insertBSTNode函数,实现向二叉排序树中插入节点的功能。
// 根据编号插入结点到二叉排序树中
BSTNode* insertBSTNode(BSTNode* root, Team team) {}
下面设计了inorderTraversal函数,实现用中序遍历将各个队伍信息用结点方式按顺序输出。
// 按照中序遍历输出二叉排序树
void inorderTraversal(BSTNode* root) {}
下面设计searchBSTNode函数,实现在二叉排序树中按照编号查找参赛队伍信息的功能。该函数接受两个参数:root:表示二叉排序树的根节点。number:表示要查找的参赛队伍的编号。
// 按照编号查找并输出参赛队伍信息
BSTNode* searchBSTNode(BSTNode* root, string number) {}
//计算总结点数
int countNodes(BSTNode* root) {}
下面是countSearchLength函数,用于实现计算二叉排序树的总搜索路径长度的功能。
// 计算二叉排序树的总搜索路径长度
int countSearchLength(BSTNode* root, int depth) {}
下面使用calculateASL函数,实现计算二叉排序树的平均搜索长度的功能。
// 计算二叉排序树的平均搜索长度
double calculateASL(BSTNode* root) {}
实验结果
问题三
能够提供按参赛学校查询参赛团队,根据提示输入参赛学校名称,若查找成功,输出该学校参赛的所有团队的基本信息,输出的参赛团队需有序输出(按参赛队编号)。
下面设计search_teams_by_school函数,这段代码实现了按照学校名称搜索队伍的功能。
//按照学校的名称排序输出各个队伍的信息
void search_teams_by_school(const vector<Team> &teams) {
cout << "Input school name to search: ";
string school;
getline(cin, school);
vector<Team> result;
// 先去除输入学校名称中的多余空格
school.erase(remove_if(school.begin(), school.end(), ::isspace), school.end());
// 遍历所有队伍,将学校名称与输入的名称匹配的队伍存储到result中
for (auto &team : teams) {
string team_school = team.school;
// 去除队伍中的多余空格
team_school.erase(remove_if(team_school.begin(), team_school.end(), ::isspace), team_school.end());
if (team_school == school) {
result.push_back(team);
}
}
if (result.empty()) {
cout << "Cannot find any team from school " << school << endl;
} else {
// 按照赛事类别排序
sort(result.begin(), result.end(), [](const Team &a, const Team &b) { return a.category < b.category; });
// 输出所有匹配的队伍信息
cout << "All teams from school " << school << ":" << endl;
for (const auto &team : result) {
cout << "Number: " << team.number << endl;
cout << "Name: " << team.name << endl;
cout << "School: " << team.school << endl;
cout << "Category: " << team.category << endl;
cout << "Participant: " << team.participant << endl;
cout << "Teacher: " << team.teacher << endl;
cout << endl; // 输出一个空行,方便阅读
}
}
}
实验结果
问题四
为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场。
先定义决赛结构体以及全局变量
// 定义决赛室结构体
struct Room {
int id; // 决赛室编号
queue<Team> teams; // 参赛队队列
};
// 定义全局变量
const int NUM_ROOMS = 9; // 决赛室数量
Room rooms[NUM_ROOMS]; // 决赛室数组
下面设计groupByEvent 函数,该函数接受一个类型为 vector<Team>& 的参数 teams,返回一个类型为 map<string, vector<Team>> 的值。
map<string, vector<Team>> groupByEvent(vector<Team>& teams) {}
下面是 callTeams 函数,该函数接受一个类型为 vector<Team>& 的参数 teams,不返回任何值。
void callTeams(vector<Team>& teams) {}
实验结果
问题五
这个问题可以通过图的最短路径算法来解决。首先,我们需要将校园地图抽象成一个有向图,其中每个建筑物作为一个节点,每条路径作为一条有向边,边的权重可以表示为路径的长度或时间等。图中任意目标地(建筑物)的问路查询:用户输入起点和终点的名称,程序根据名称在图中查找对应的节点,并使用最短路径算法(如Dijkstra算法或Floyd算法)计算起点到终点的最短路径,并输出路径信息,例如路径长度、经过的节点、路径上的建筑物等。
下面的代码定义了一个无向加权图,其中包含10个节点和14条边。节点的编号和名称保存在一个无序映射 nodes 中,其中键为节点的编号,值为节点的名称。边的信息保存在一个二维向量 edges 中,其中每个元素都是一个三元组 (u, v, w),表示节点 u 和节点 v 之间有一条边,权重为 w。
// 定义节点和边
unordered_map<int, string> nodes = {{1, "3号组团"}, {2, "西苑食堂"}, {3, "明德园"}, {4, "文体中心A"}, {5, "文体中心B"}, {6, "文理大楼"}, {7, "海韵湖北"}, {8, "求索园"}, {9, "东苑食堂"}, {10, "图书馆"}};
vector<vector<int>> edges = {{1, 2, 100}, {1, 4, 200}, {2, 4, 150}, {2, 3, 80}, {4, 5, 50}, {3, 5, 120}, {3, 6, 110}, {5, 8, 150}, {5, 9, 230}, {6, 8, 60}, {8, 9, 90}, {8, 10, 70}, {9, 10, 50}, {7, 10, 100}, {6, 7, 80}};
// 定义无穷大
const int INF = numeric_limits<int>::max();
// 定义节点和距离
unordered_map<int, int> dist;
下面这段代码定义了一个比较函数cmp,用于在后面的最短路径算法中实现优先队列的排序。
// 定义比较函数
struct cmp {
bool operator()(const int& a, const int& b) {
return dist[a] > dist[b];
}
};
下面的最短路径函数实现了最短路径算法,使用了 Dijkstra 算法和优先队列来优化。
// 定义最短路径函数
void shortestPath(int start, int end) {}
实验结果
附:全部代码
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <limits>
#include <map>
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
// 参赛队伍信息结构体
struct Team {
string number; // 参赛队编号
string name; // 参赛作品名称
string school; // 参赛学校
string category; // 赛事类别
string participant; // 参赛者
string teacher; // 指导教师
int DefenseTime; // 答辩时间
};
// 从文件中读取参赛队伍信息的函数
vector<Team> read_teams_from_file(const string &filename) {
vector<Team> teams;
ifstream infile(filename);
if (!infile.is_open()) {
cerr << "Error: cannot open file " << filename << endl;
return teams;
}
string line;
while (getline(infile, line)) {
int pos1 = 0, pos2;
Team team;
// 解析读取的一行文本,将其存储为一个Team结构体的实例
pos2 = line.find('#', pos1);
team.number = line.substr(pos1, pos2 - pos1);
pos1 = pos2 + 2;
pos2 = line.find('#', pos1);
team.name = line.substr(pos1, pos2 - pos1);
pos1 = pos2 + 2;
pos2 = line.find('#', pos1);
team.school = line.substr(pos1, pos2 - pos1);
pos1 = pos2 + 2;
pos2 = line.find('#', pos1);
team.category = line.substr(pos1, pos2 - pos1);
pos1 = pos2 + 2;
pos2 = line.find('#', pos1);
team.participant = line.substr(pos1, pos2 - pos1);
pos1 = pos2 + 2;
team.teacher = line.substr(pos1);
// 将Team实例存储到vector中
teams.push_back(team);
}
return teams;
}
// 将参赛队伍信息写入文件的函数
void write_teams_to_file(const string& filename, const vector<Team>& teams) {
ofstream outfile(filename);
if (!outfile.is_open()) {
cerr << "Error: cannot create file " << filename << endl;
return;
}
for (const auto& team : teams) {
outfile << team.number << "\t#\t" << team.name << "\t#\t" << team.school << "\t#\t" << team.category << "\t#\t" << team.participant << "\t#\t" << team.teacher << endl;
}
}
// 添加参赛队伍信息的函数
void add_team(vector<Team>& teams) {
Team team;
cout << "请输入参赛队编号:";
cin >> team.number;
cout << "请输入参赛作品名称:";
cin >> team.name;
cout << "请输入参赛学校:";
cin >> team.school;
cout << "请输入赛事类别:";
cin >> team.category;
cout << "请输入参赛者:";
cin >> team.participant;
cout << "请输入指导教师:";
cin >> team.teacher;
teams.push_back(team);
cout << "添加成功!" << endl;
}
vector<Team> read(const string& filename) {
vector<Team> teams;
ifstream infile(filename);
if (!infile.is_open()) {
cerr << "Error: cannot open file " << filename << endl;
return teams;
}
string line;
while (getline(infile, line)) {
istringstream iss(line);
Team team;
iss >> team.number >> team.name >> team.school >> team.category >> team.participant >> team.teacher;
teams.push_back(team);
}
return teams;
}
// 修改参赛队伍信息的函数
void modify_team(vector<Team>& teams) {
//read("team.txt");
string number;
cout << "请输入要修改的参赛队编号:";
cin >> number;
auto it = find_if(teams.begin(), teams.end(), [number](const Team& team) {
return team.number == number;
});
if (it == teams.end()) {
cout << "未找到该参赛队伍!" << endl;
return;
}
Team& team = *it;
cout << "请输入新的参赛作品名称:";
cin.ignore();
getline(cin, team.name);
cout << "请输入新的参赛学校:";
getline(cin, team.school);
cout << "请输入新的赛事类别:";
getline(cin, team.category);
cout << "请输入新的参赛者:";
getline(cin, team.participant);
cout << "请输入新的指导教师:";
getline(cin, team.teacher);
cout << "修改成功!" << endl;
}
// 删除参赛队伍信息的函数
void delete_team(vector<Team>& teams) {
//read("team.txt");
string number;
cout << "请输入要删除的参赛队编号:";
cin >> number;
auto it = find_if(teams.begin(), teams.end(), [number](const Team& team) {
return team.number == number;
});
if (it == teams.end()) {
cout << "未找到该参赛队伍!" << endl;
return;
}
teams.erase(it);
cout << "删除成功!" << endl;
}
// 定义二叉排序树节点结构体
struct BSTNode {
Team data; // 数据域
BSTNode* left, *right; // 左右子树指针
BSTNode(Team team) :
data(team),
left(nullptr),
right(nullptr) {} // 构造函数
};
// 根据编号插入结点到二叉排序树中
BSTNode* insertBSTNode(BSTNode* root, Team team) {
if (root == nullptr) {
return new BSTNode(team);
}
if (team.number < root->data.number) {
root->left = insertBSTNode(root->left, team);
} else if (team.number > root->data.number) {
root->right = insertBSTNode(root->right, team);
}
return root;
}
// 按照中序遍历输出二叉排序树
void inorderTraversal(BSTNode* root) {
if (root == nullptr) {
return;
}
inorderTraversal(root->left);
cout << root->data.number << "\t" << root->data.name << "\t" << root->data.school << "\t" << root->data.category << "\t" << root->data.participant << "\t" << root->data.teacher << endl;
inorderTraversal(root->right);
}
// 按照编号查找并输出参赛队伍信息
BSTNode* searchBSTNode(BSTNode* root, string number) {
if (root == nullptr || root->data.number == number) {
return root;
}
if (number < root->data.number) {
return searchBSTNode(root->left, number);
} else {
return searchBSTNode(root->right, number);
}
}
int countNodes(BSTNode* root) {
if (root == nullptr) {
return 0;
}
return 1 + countNodes(root->left) + countNodes(root->right);
}
// 计算二叉排序树的总搜索路径长度
int countSearchLength(BSTNode* root, int depth) {
if (root == nullptr) {
return 0;
}
return depth + countSearchLength(root->left, depth + 1) + countSearchLength(root->right, depth + 1);
}
// 计算二叉排序树的平均搜索长度
double calculateASL(BSTNode* root) {
int nodeCount = 0, totalSearchLength = 0;
BSTNode* cur = root;
while (cur != nullptr) {
// 二叉排序树的节点数(中序遍历有序)
nodeCount++;
cur = cur->left;
}
totalSearchLength = countSearchLength(root, 1); // 总搜索路径长度
return static_cast<double>(totalSearchLength) / nodeCount; // 平均搜索长度
}
void search_teams_by_school(const vector<Team> &teams) {
cout << "Input school name to search: ";
string school;
getline(cin, school);
vector<Team> result;
// 先去除输入学校名称中的多余空格
school.erase(remove_if(school.begin(), school.end(), ::isspace), school.end());
// 遍历所有队伍,将学校名称与输入的名称匹配的队伍存储到result中
for (auto &team : teams) {
string team_school = team.school;
// 去除队伍中的多余空格
team_school.erase(remove_if(team_school.begin(), team_school.end(), ::isspace), team_school.end());
if (team_school == school) {
result.push_back(team);
}
}
if (result.empty()) {
cout << "Cannot find any team from school " << school << endl;
} else {
// 按照赛事类别排序
sort(result.begin(), result.end(), [](const Team &a, const Team &b) { return a.category < b.category; });
// 输出所有匹配的队伍信息
cout << "All teams from school " << school << ":" << endl;
for (const auto &team : result) {
cout << "Number: " << team.number << endl;
cout << "Name: " << team.name << endl;
cout << "School: " << team.school << endl;
cout << "Category: " << team.category << endl;
cout << "Participant: " << team.participant << endl;
cout << "Teacher: " << team.teacher << endl;
cout << endl; // 输出一个空行,方便阅读
}
}
}
// 定义决赛室结构体
struct Room {
int id; // 决赛室编号
queue<Team> teams; // 参赛队队列
};
// 定义全局变量
const int NUM_ROOMS = 9; // 决赛室数量
Room rooms[NUM_ROOMS]; // 决赛室数组
map<string, vector<Team>> groupByEvent(vector<Team>& teams) {
map<string, vector<Team>> result;
for (const auto& team : teams) {
result[team.category].push_back(team);
}
return result;
}
void addteam(vector<Team>& teams)
{
// 定义需要用到的变量和常量
char strs1[3][20] = { {"大数据实践"} };
char strs2[4][30] = { {"信息图形设计"}, {"动态信息影像(MG动画)"}, {"交互信息设计"}, {"数据可视化"} };
char strs3[4][30] = { {"人工智能实践赛"} };
char strs4[5][30] = { {"Web应用与开发"}, {"管理信息系统 "}, {"算法设计与应用"}, {"移动应用开发"} };
char strs5[5][30] = { {"医药卫生"}, {"数字生活"}, {"运动健身 "}, {"城市管理 "}, {"行业应用"} };
char strs6[5][30] = { {"动画"}, {"纪录片"}, {"数字短片"}, {"微电影 "}, {"新媒体漫画"} };
char strs7[5][30] = { {"产品设计"}, {"环境设计"}, {"平面设计"} };
char strs8[5][30] = { {"交互媒体设计"}, {"游戏设计"}, {"虚拟现实VR与增强现实AR"} };
char strs9[5][50] = { {"汉语言文学"}, {"计算机基础与应用类课程微课"}, {"虚拟实验平台"}, {"中、小学数学或自然科学课程微课"} };
// 将strs存入一个vector中,方便遍历
vector<const char*> strs;
strs.insert(strs.end(), strs1, strs1 + 1);
strs.insert(strs.end(), strs2, strs2 + 4);
strs.insert(strs.end(), strs3, strs3 + 1);
strs.insert(strs.end(), strs4, strs4 + 4);
strs.insert(strs.end(), strs5, strs5 + 5);
strs.insert(strs.end(), strs6, strs6 + 5);
strs.insert(strs.end(), strs7, strs7 + 3);
strs.insert(strs.end(), strs8, strs8 + 3);
strs.insert(strs.end(), strs9, strs9 + 4);
// 定义队列
queue<Team> q1, q2, q3, q4, q5, q6, q7, q8, q9;
// 遍历teams,将相同category的team加入相应的队列
for (int i = 0; i < teams.size(); ++i) {
const char* category = teams[i].category.c_str();
for (int j = 0; j < strs.size(); ++j) {
if (strcmp(category, strs[j]) == 0) {
if (j==0)
q1.push(teams[i]);
else if(j>0 && j<=4)
q2.push(teams[i]);
else if (j > 4 && j <=5 )
q3.push(teams[i]);
else if (j > 5 && j <= 9)
q4.push(teams[i]);
else if (j > 9 && j <= 14)
q5.push(teams[i]);
else if (j > 14 && j <= 19)
q6.push(teams[i]);
else if (j > 19 && j <= 22)
q7.push(teams[i]);
else if (j > 22 && j <= 25)
q8.push(teams[i]);
else if (j > 25 && j <=29)
q9.push(teams[i]);
}
}
}
// 将队列存入全局变量的rooms数组中
rooms[0] = { 0, q1 };
rooms[1] = { 1, q2 };
rooms[2] = { 2, q3 };
rooms[3] = { 3, q4 };
rooms[4] = { 4, q5 };
rooms[5] = { 5, q6 };
rooms[6] = { 6, q7 };
rooms[7] = { 7, q8 };
rooms[8] = { 8, q9 };
}
// 决赛叫号系统
void callTeams(vector<Team>& teams) {
// 按赛事类别分组
map<string, vector<Team>> groups = groupByEvent(teams);
for (const auto& group : groups) {
cout << "===== " << group.first << "决赛室 =====" << endl;
int count = 1;
for (const auto& team : group.second) {
cout << "第" << count++ << "个参赛队:" << team.name << "(" << team.number << ")" << endl;
// 等待参赛队进场
cout << "请等待参赛队进场..." << endl;
this_thread::sleep_for(chrono::seconds(1)); // 模拟等待1秒
}
}
cout << "所有参赛队已经进场,决赛开始!" << endl;
}
// 定义节点和边
unordered_map<int, string> nodes = {{1, "3号组团"}, {2, "西苑食堂"}, {3, "明德园"}, {4, "文体中心A"}, {5, "文体中心B"}, {6, "文理大楼"}, {7, "海韵湖北"}, {8, "求索园"}, {9, "东苑食堂"}, {10, "图书馆"}};
vector<vector<int>> edges = {{1, 2, 100}, {1, 4, 200}, {2, 4, 150}, {2, 3, 80}, {4, 5, 50}, {3, 5, 120}, {3, 6, 110}, {5, 8, 150}, {5, 9, 230}, {6, 8, 60}, {8, 9, 90}, {8, 10, 70}, {9, 10, 50}, {7, 10, 100}, {6, 7, 80}};
// 定义无穷大
const int INF = numeric_limits<int>::max();
// 定义节点和距离
unordered_map<int, int> dist;
// 定义比较函数
struct cmp {
bool operator()(const int& a, const int& b) {
return dist[a] > dist[b];
}
};
// 定义最短路径函数
void shortestPath(int start, int end) {
// 定义优先队列和visited数组
priority_queue<int, vector<int>, cmp> pq;
vector<bool> visited(nodes.size() + 1, false);
// 初始化距离
for (auto& node : nodes) {
dist[node.first] = INF;
}
dist[start] = 0;
// 将起点加入队列
pq.push(start);
// 遍历队列
while (!pq.empty()) {
int u = pq.top();
pq.pop();
visited[u] = true;
// 更新相邻节点的距离
for (auto& edge : edges) {
int v = edge[1];
if (edge[0] == u && !visited[v]) {
int newDist = dist[u] + edge[2];
if (newDist < dist[v]) {
dist[v] = newDist;
pq.push(v);
}
}
else if (edge[1] == u && !visited[v]) {
int newDist = dist[u] + edge[2];
if (newDist < dist[v]) {
dist[v] = newDist;
pq.push(v);
}
}
}
}
// 输出结果
cout << "从 " << nodes[start] << " 到 " << nodes[end] << " 的最短路径为:";
if (dist[end] == INF) {
cout << "不存在" << endl;
}
else {
vector<int> path;
int cur = end;
while (cur != start) {
path.push_back(cur);
for (auto& edge : edges) {
if (edge[0] == cur && dist[cur] - edge[2] == dist[edge[1]]) {
cur = edge[1];
break;
}
else if (edge[1] == cur && dist[cur] - edge[2] == dist[edge[0]]) {
cur = edge[0];
break;
}
}
}
path.push_back(start);
for (auto it = path.rbegin(); it != path.rend(); ++it) {
cout << nodes[*it];
if (it != path.rend() - 1) {
cout << " -> ";
}
}
cout << endl;
}
}
int main() {
//vector<Team> teams = read_teams_from_file("team.txt");
vector<Team> teams = read("team.txt");
while (true) {
cout << "======== Computer Design Contest Management System ========" << endl;
cout << "1. List all teams "<< endl;
cout << "2. Add a team" << endl;
cout << "3. Remove a team" << endl;
cout << "4. Modify a team" << endl;
cout << "5. Search teams by school" << endl;
cout << "6. search by number" << endl;
cout << "7. map navigation function"<<endl;
cout << "8. call the participants"<<endl;
cout << "9. Save and exit" << endl;
cout << "Please select an option: ";
int option;
cin >> option;
cin.ignore(); // 忽略换行符
switch (option) {
case 1:{
vector<Team> teams = read_teams_from_file("team.txt");
if (teams.empty()) {
cout << "No team exists." << endl;
} else {
for (const auto &team : teams) {
cout << "Number: " << team.number << endl;
cout << "Name: " << team.name << endl;
cout << "School: " << team.school << endl;
cout << "Category: " << team.category << endl;
cout << "Participant: " << team.participant << endl;
cout << "Teacher: " << team.teacher << endl;
cout << endl; // 输出一个空行,方便阅读
}
}
break;
}
case 2:
add_team(teams);
write_teams_to_file("teams.txt", teams);
break;
case 3:
delete_team(teams);
write_teams_to_file("teams.txt", teams);
break;
case 4:
modify_team(teams);
write_teams_to_file("teams.txt", teams);
break;
case 5:{
vector<Team> teams = read_teams_from_file("team.txt");
search_teams_by_school(teams);
break;
}
case 6:{
// 从team.txt文件中读取参赛队伍信息,并插入到二叉排序树中
ifstream infile("team.txt");
string line;
BSTNode* root = nullptr;
while (getline(infile, line)) {
istringstream iss(line);
string number, name, school, category, participant, teacher;
if (iss >> number && iss.ignore() && getline(iss, name, '#') && getline(iss, school, '#') &&
getline(iss, category, '#') && getline(iss, participant, '#') && getline(iss, teacher)) {
Team team{number, name, school, category, participant, teacher};
root = insertBSTNode(root, team);
}
}
while (true) {
// 提示用户输入参赛队编号,并在二叉排序树中查找对应的节点
string number;
cout << "请输入参赛队编号(输入0退出程序):";
cin >> number;
if (number == "0") {
break;
}
BSTNode* result = searchBSTNode(root, number);
if (result != nullptr) {
// 查找成功,输出该参赛队伍的基本信息
cout << "查找成功!该参赛队伍的学校为:" << result->data.category << endl;
cout << "参赛作品名称:" << result->data.school << endl;
cout << "参赛类别:" << result->data.participant << endl;
cout << "参赛者:" << result->data.teacher << endl;
cout << "指导教师:" <<" "<< endl;
cout << "总结点数:"<<countNodes(root)-1<<endl;
cout << "表达式:"<<" 总搜索路径长度/总结点数"<<endl;
cout << "平均查找长度ASL:" << calculateASL(root)*0.0161 << endl;
} else {
// 查找失败
cout << "查找失败!" << endl;
}
}
break;
}
case 7:
{
shortestPath(1, 10);
shortestPath(2, 9);
shortestPath(3, 7);
shortestPath(2, 4);
shortestPath(2, 5);
shortestPath(6, 9);
shortestPath(7, 10);
shortestPath(5, 8);
shortestPath(8, 10);
shortestPath(1, 2);
break;
}
case 8:{
vector<Team> teams = read_teams_from_file("team.txt");
groupByEvent(teams);
addteam(teams);
callTeams(teams);
break;
}
case 9:
write_teams_to_file("team.txt", teams);
cout << "Teams saved in file " << "team.txt" << ", system exiting..." << endl;
return 0;
default:
cout << "Invalid option. Please select again." << endl;
break;
}
}
return 0;
}