《数据结构课程设计》任务书
- 熟练掌握线性表、栈、队列、串、数组、树和图等基本数据结构的逻辑特性和存储表示方法;熟练掌握各种基本数据结构的基本算法和其应用;熟练掌握问题分析、数据结构设计、程序设计的基本技能和技术。
- 能够综合运用数据结构与算法和相关的数学等理论知识对复杂工程中的算法问题进行抽象、分析和建模;能够依据工程实际问题的需求合理组织数据、并在计算机中有效地存储数据;能够针对复杂工程中的算法问题,设计出比较合理的解决方案,利用具体的编程语言实现解决方案,并具有一定的创新思维能力。
- 具有良好的工程素养和职业素养,诚信守法,能够坚持职业操守和道德规范;具有精益求精的工匠精神、创新精神和探索未知终身学习的意识;具有科技报国的社会责任感、使命感和爱国主义情操。
一.课程设计的要求
- 问题分析和任务定义:根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么,限制的条件是什么。
- 逻辑设计:对问题中涉及到的操作对象定义相应的数据类型,并按照以数据结构为中心的原则划分模块,定义主程序和各抽象数据类型,逻辑设计的结果应写出每个抽象数据类型的定义(包括数据结构的描述和每个基本操作的功能说明),各个主要模块的算法,并画出模块之间的调用关系图。
- 物理设计:定义相应的存储结构并写出各函数的伪码算法。在这个过程中,要综合考虑系统功能,使得系统结构清晰、合理、简单和易于调试,抽象数据类型的实现尽可能做到数据封装,基本操作的规格说明尽可能明确具体。详细设计的结果是对数据结构和基本操作做出进一步的求精,写出数据结构存储结构的类型定义,写出函数形式的算法框架。
- 程序编码:把详细设计的结果进一步求精为程序设计语言。同时加入一些注解和断言,使程序中逻辑概念清晰。
- 程序调试和测试:采用自底向上,分模块进行,即先调试低层函数。能够熟练掌握调试工具的各种功能,设计测试数据确定疑点,通过修改程序来证实它或绕过它。调试正确后,认真整理源程序和注释,形成格式和风格良好的源程序清单和结果。
- 结果分析:程序运行结果包括正确的输入及其输出结果、含有错误的输入和输出结果、算法时间复杂度和空间复杂度分析。
- 撰写课程设计报告:总结和提升上述过程和步骤,写出结构严谨、表述清楚、符合设计规范的报告。
二.课程设计内容
中国大学生计算机设计大赛省级赛事管理系统
中国大学生计算机设计大赛是我国高校面向本科生的计算机应用设计大赛,大赛旨在激发学生学习计算机知识和技能的兴趣与潜能,提高学生运用信息技术解决实际问题的综合能力。通过大赛这种计算机教学实践形式,可展示师生的教与学成果,最终以赛促学,以赛促教,以赛促创。该赛事在历届学生中影响力较大,参与者众多。
请了解该赛事组织及管理方式,利用数据结构课程所学的相关知识,为中国大学生计算机设计大赛江苏省组委会设计一个省级赛事管理系统。以2021年省赛数据为例,通过对数据的处理和分析,设计合理的数据结构对赛事相关的数据进行存储及处理。赛事相关数据存储在文本文件和excel文件中,文件中不同的数据项之间均使用#分隔,图1中给出了文件team.txt中参赛信息的对应数据示例。
图1. 参赛队基本信息
【任务描述】
设计一款赛事管理系统,实现赛务相关的数据管理及信息服务,该系统能够为省级赛事管理解决以下问题:
- 赛事信息管理:从team.txt中读取参赛队伍的基本信息,设计合适的数据结构存储,能实现对参赛队伍的增加、修改和浏览。为参赛队伍分配一个分数为60~100之间的初赛成绩,并能实现参赛队伍的成绩查询(实现基于二叉排序树的查找)。设计合适的输入输出,根据提示输入参赛队编号,查询队伍的初赛成绩,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和初赛成绩信息)。另外,输出全部参赛队的平均查找长度ASL。
(2)决赛现场模拟:首先进行决赛分组,生成决赛秩序册,供参赛队查询。根据赛事类别将参赛队伍分配到17个决赛室(编号为1~17)。秩序册中每个决赛室的进场顺序为初赛成绩降序排列。(排序算法从选择排序、插入排序、希尔排序、归并排序、堆排序中选择一种,并为选择该算法的原因做出说明)然后,模拟决赛秩序。比赛现场会设置大型候赛区,场地中有大屏以时间线动态展示各决赛室中正在决赛的队伍,侯赛的队伍及比赛结束的队伍信息。请编写程序模拟候赛区大屏上动态展示各参赛队候场、比赛中、比赛结束的状态。
(3)决赛地图导览:为参赛者提供决赛主办地的各种路径导航的查询服务,以我校长山校区提供比赛场地为例,为参赛者提供不少于12个目标地的导航。为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供图中任意目标地(建筑物)的问路查询。
【任务要求】
- 请根据任务描述的问题,设计合理的菜单,菜单交互设计要合理,便于用户根据提示使用系统的所有功能。
- 赛事数据要求从文件(txt或excel)读入,修改后的信息能存入文件。
3)第三个任务赛地目的地查询,需输出目的地(建筑物)名称、代号、简介等信息;最短路径的输出需包含途经地及最短路径值;并分析主要算法的时间复杂度。
4)请自行设计测试数据。使用全部合法数据,整体非法数据,局部非法数据对程序测试,以保证程序的健壮性。
5)编码时请注意规范代码结构,重要的变量,函数要有清晰的注释;注重代码的效率和可重用性,实现低耦合、高内聚,不要将各种功能混在一个方法中编写。
【实现步骤提示】
1)分析任务,进行功能设计,菜单设计;
2)定义数据结构,建议按照抽象数据类型的定义、表示和实现来描述,用类C语言(伪代码)来描述数据的存储表示和相应操作的具体实现过程。
3)设计合适的算法来实现其功能,并绘制函数调用关系图
备注:第(3)项任务决赛地以江苏科技大学长山校区为例,图例如下:
可制作如下网络示意图。
预习日志:
12.11日,完成任务一中文本读取,成绩添加,二叉排序树建立。
12.12日,完成任务一文本读取修改删除,成绩添加。
12.13日,完成任务三中查找路线
12.14日,完成任务二,分配队伍,队伍比赛时的动态展示
12.15日,没写
12.16日,没写
12.17日,开始写交互界面,完成交互界面的界面背景以及鼠标信息获取。
界面交互已完成。
环境配置:
添加了easyx库进行交互界面的设计,运行前需要在官网下载easyx_20220901后解压放在include以及lib下,在项目链接中添加-leasyx。
运行所需要的头文件
#include <string>
#include <queue>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <graphics.h>
#include <algorithem>
#include <window.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
1.赛事信息管理:
构建了一个结构体team以及一个比赛管理类
struct team{//team类,存储参赛队伍的各种信息
string team_number;//参赛编号
string team_name;//参赛队伍的项目名字
string team_school;//参赛队伍的学校
string team_cateory;//参赛队伍的类别
string team_sutdent;//参赛者
string team_teacher;//指导老师
int score;
};
class manager{//赛事管理类
public:
manager();//建表
void change(string str);//改变一个队伍的相关数据,输入的s为队伍的编号
void add();//添加一个队伍
int delete_team(string str);//删除一个队伍的相关数据,输入的str为队伍的编号
team seacher(string str);//查找一个队伍的相关资料
void reset(int pos);//在删除了部分元素后对数组内容的重新划分
void scoreadd();//添加成绩
void print();
int getnum();
team* getnode();
~manager();//析构函数
private:
team t[500];//存数据
int num=0;//记录当前存了多少个队伍
};
通过构造函数对于文本数据进行读取
manager::manager(){//管理类的构造函数
ifstream readfile;
readfile.open("team.txt",ios::in);//读出文件数据
if(readfile.is_open()){
char s;
string s1;
int i=0;//记录已读的行数
int b=0;//记录当前需要存储的数据类型
while((s=readfile.get())!=EOF){
if(s=='\n'){
b=0;
i++;
}
if(s=='#'){
b++;
}
if(s!='\0'&&s!='\t'&&s!='#'&&s!='\n'){
if(b==0){
t[i].team_number+=s;
}else if(b==1){
t[i].team_name+=s;
}else if(b==2){
t[i].team_school+=s;
}else if(b==3){
t[i].team_cateory+=s;
}else if(b==4){
t[i].team_sutdent+=s;
}else if(b==5){
t[i].team_teacher+=s;
}
}
}
num=i;
}
readfile.close();
}
将文本中的数据依次存入结构体数组中,而对于文本的增加删除修改中则是分别运用了ios::out,iOS::app,两种模式分别是对于文本的覆盖重写,与对文本的追加
void manager::add(){//添加队伍
ofstream ofs;
ofs.open("team.txt",ios::app);
num++;
cout<<"请输入队伍编号"<<"\n";
cin>>t[num].team_number;
cout<<"请输入队伍项目名称"<<"\n";
cin>>t[num].team_name;
cout<<"请输入队伍学校"<<"\n";
cin>>t[num].team_school;
cout<<"请输入队伍项目类别"<<"\n";
cin>>t[num].team_cateory;
cout<<"请输入队伍参赛队员与指导老师"<<"\n";
cin>>t[num].team_sutdent>>t[num].team_teacher;
ofs<<t[num].team_number<<"\t"<<"#"<<"\t"<<t[num].team_name<<"\t"<<"#"<<"\t"<<t[num].team_school<<"\t"<<"#"<<"\t"<<t[num].team_cateory<<"\t"<<"#"<<"\t"<<t[num].team_sutdent<<"\t"<<"#"<<"\t"<<t[num].team_teacher<<"\n";
ofs.close();
system("cls");
}
int manager::delete_team(string str){//队伍删除
ifstream readfile;
readfile.open("team1.txt",ios::in);//读出文件数据
int linenum=1;//记录所找数据在第几行
if(readfile.is_open()){
char s;
string s1;
while((s=readfile.get())!=EOF){
if(s=='\n'){
s1="";
linenum++;
}
if(s!='\0'&&s!='\t'&&s!='#'&&s!='\n'){
s1+=s;
if(s1==str){
break;
}
}
}
}
if(linenum==num+1){
cout<<"改队伍已删除";
return -1;
}
readfile.close();
ofstream ofs;
ofs.open("team1.txt",ios::out);
int b=1;
int pos=0;
while(pos!=num){
if(pos!=linenum-1){
ofs<<t[pos].team_number<<"\t"<<"#"<<"\t"<<t[pos].team_name<<"\t"<<"#"<<"\t"<<t[pos].team_school<<"\t"<<"#"<<"\t"<<t[pos].team_cateory<<"\t"<<"#"<<"\t"<<t[pos].team_sutdent<<"\t"<<"#"<<"\t"<<t[pos].team_teacher<<"\n";
}
pos++;
}
reset(linenum);
ofs.close();
sleep(8);
system("cls");
return pos;
}
void manager::change(string str){//队伍修改
ifstream readfile;
readfile.open("team1.txt",ios::in);//读出文件数据
int linenum=1;//记录所找数据在第几行
if(readfile.is_open()){
char s;
string s1;
while((s=readfile.get())!=EOF){
if(s=='\n'){
s1="";
linenum++;
}
if(s!='\0'&&s!='\t'&&s!='#'&&s!='\n'){
s1+=s;
if(s1==str){
break;
}
}
}
}
if(linenum==num+1){
cout<<"改队伍已删除";
return ;
}
readfile.close();
ofstream ofs;
ofs.open("team1.txt",ios::out);
int b=1;
int pos=0;
while(pos!=num){
if(pos!=linenum-1){
cout<<"please reset the sat"<<"\n" ;
cout<<"请输入队伍编号"<<"\n";
cin>>t[pos].team_number;
cout<<"请输入队伍项目名称"<<"\n";
cin>>t[pos].team_name;
cout<<"请输入队伍学校"<<"\n";
cin>>t[pos].team_school;
cout<<"请输入队伍项目类别"<<"\n";
cin>>t[pos].team_cateory;
cout<<"请输入队伍参赛队员与指导老师"<<"\n";
cin>>t[pos].team_sutdent>>t[pos].team_teacher;
ofs<<t[pos].team_number<<"\t"<<"#"<<"\t"<<t[pos].team_name<<"\t"<<"#"<<"\t"<<t[pos].team_school<<"\t"<<"#"<<"\t"<<t[pos].team_cateory<<"\t"<<"#"<<"\t"<<t[pos].team_sutdent<<"\t"<<"#"<<"\t"<<t[pos].team_teacher<<"\n";
pos++;
continue;
}
ofs<<t[pos].team_number<<"\t"<<"#"<<"\t"<<t[pos].team_name<<"\t"<<"#"<<"\t"<<t[pos].team_school<<"\t"<<"#"<<"\t"<<t[pos].team_cateory<<"\t"<<"#"<<"\t"<<t[pos].team_sutdent<<"\t"<<"#"<<"\t"<<t[pos].team_teacher<<"\n";
pos++;
}
ofs.close();
system("cls");
}
而在基于二叉排序树的成绩查询中,分别构造了树节点Node,与二叉排序树类
class bintree{//二叉排序树的类
public:
bintree(team *t,int num);//建树
Node* insert(Node*bt,team t);//插入节点
void seacher1(Node*p,int k);//查找对应成绩
Node* getroot();//得到根节点
double clc(int x);
void prorder(Node*p,int k);
~bintree();
private:
Node*root;//根节点
int asl;
};
struct Node{//二叉排序树的节点
int number;//队伍编号
int score;//队伍成绩
Node*lnext;//左节点
Node*rnext;//右节点
};
对于二叉排序树的查询以及其平均查找的计算中,声明了类中私有变量存储节点所在层数之和
void bintree::seacher1(Node*p,int k){//查找对应编号的成绩
if(p==NULL){
return ;
}
if(p->number==k){
cout<<p->score;
}
seacher1(p->lnext,k);
seacher1(p->rnext,k);
}
void bintree::prorder(Node*p,int k){//遍历平衡二叉树,并计算asl
if(p==NULL){
return ;
}
asl+=1*k;
prorder(p->lnext,++k);
prorder(p->rnext,++k);
}
而在关于队伍分组的情况下,参照了2021计算机设计大赛决赛分组,为17个队列附上初始标签,从而将所有队伍放在17个队伍中
struct divd{
string cate1;
string cate2;
string cate3;
string cate4;
team t[50];
};
competition::competition(team *t,int num){
c[0].cate1="大数据实践";
c[0].cate2="信息图形设计";
c[1].cate1="动态信息影像(MG动画)";
c[1].cate2="交互信息设计";
c[1].cate3="数据可视化";
c[2].cate1="人工智能实践赛";
c[3].cate1="人工智能实践赛";
c[4].cate1="Web应用与开发";
c[4].cate2="管理信息系统";
c[5].cate1="算法设计与应用";
c[6].cate1="移动应用开发";
c[6].cate2="医药卫生";
c[7].cate1="数字生活";
c[7].cate2="运动健身";
c[7].cate3="行业应用";
c[7].cate4="城市管理";
c[8].cate1="动画";
c[8].cate2="纪录片";
c[9].cate1="微电影";
c[9].cate2="新媒体漫画";
c[10].cate1="环境设计";
c[10].cate2="产品设计";
c[11].cate1="平面设计";
c[12].cate1="交互媒体设计";
c[12].cate2="游戏设计";
c[12].cate3="虚拟现实VR与增强现实AR";
c[13].cate1="汉语言文学";
c[13].cate2="计算机基础与应用类课程微课";
c[14].cate1="虚拟实验平台";
c[15].cate1="中、小学数学或自然科学课程微课";
for(int i=0;i<=16;i++){
int pos=0;
cout<<"\n";
for(int j=1;j<=num;j++){
if(i==16&&!b[j]){
c[i].t[pos++]=t[j];
// cout<<j<<"\n";
b[j]=true;
continue;
}
if(pos>24&&!b[j]){
continue;
}
if(t[j].team_cateory==c[i].cate1&&!b[j]){
b[j]=true;
c[i].t[pos++]=t[j];
}else if(t[j].team_cateory==c[i].cate2&&!b[j]){
b[j]=true;
c[i].t[pos++]=t[j];
}else if(t[j].team_cateory==c[i].cate3&&!b[j]){
b[j]=true;
c[i].t[pos++]=t[j];
}else if(t[j].team_cateory==c[i].cate4&&!b[j]){
b[j]=true;
c[i].t[pos++]=t[j];
}
}
}
}
对于在比赛进程中的显示,则是在排序后不断输入队头元素,通过sleep模拟比赛进程。
void competition::coming(){
for(int i=0;;i++){
cout<<c[0].t[i].team_name<<" ing\n";
cout<<c[1].t[i].team_name<<" ing\n";
cout<<c[2].t[i].team_name<<" ing\n";
cout<<c[3].t[i].team_name<<" ing\n";
cout<<c[4].t[i].team_name<<" ing\n";
cout<<c[5].t[i].team_name<<" ing\n";
cout<<c[6].t[i].team_name<<" ing\n";
cout<<c[7].t[i].team_name<<" ing\n";
cout<<c[8].t[i].team_name<<" ing\n";
cout<<c[9].t[i].team_name<<" ing\n";
cout<<c[10].t[i].team_name<<" ing\n";
cout<<c[11].t[i].team_name<<" ing\n";
cout<<c[12].t[i].team_name<<" ing\n";
cout<<c[13].t[i].team_name<<" ing\n";
cout<<c[14].t[i].team_name<<" ing\n";
cout<<c[15].t[i].team_name<<" ing\n";
cout<<c[16].t[i].team_name<<" ing\n";
sleep(5);
cout<<"请下一队上前"<<"\n";
sleep(2);
system("cls");
}
}
而在查找路径过程中,定义了寻路类使用了小根堆优化dijkstra算法,
class road{//找路类
public:
road();//构造函数,通过dijkstra算法对于单源最短路的求解
void seachroad(int s,int e);//寻找路径
private:
int d[10][10];
};
typedef pair<int ,int>PII;
const int N=1e6+10;
int n,m;
int h[N],w[N],e[N],ne[N],idx;
int dist[N];
bool st[N];
void add(int a,int b,int c){
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int dijkstra(){
memset(dist,0x3f,sizeof dist);
dist[1]=0;
priority_queue<PII,vector<PII>,greater<PII> >heap;
heap.push({0,1});
while(heap.size()){
auto t=heap.top();
heap.pop();
int ver=t.second,distance=t.first ;
if(st[ver])continue;
st[ver]=true;
for(int i=h[ver];i!=-1;i=ne[i]){
int j=e[i];
if(dist[j]>dist[ver]+w[i]){
dist[j]=dist[ver]+w[i];
heap.push({dist[j],j});
}
}
}
if(dist[n]==0x3f3f3f)return -1;
return dist[n];
}
交互界面的设计中,构建了按纽以及列表类
class BUTTON{
public:
BUTTON();
void drawbutton(int pos);//画按纽
bool mouseintbutton(int pos,MOUSEMSG mouse);//判断按钮是否在区域中
int clickbutton(int pos,MOUSEMSG mouse);//判断是否按下按钮
private:
button b[20];//按键
};
struct button{//定义交互界面的按钮
int x;
int y;
int w;
int h;
COLORREF color;
string word;
};
在按键的实现过程中,对于按键的位置,颜色,字体依次赋值,并通过drawbutton将其放在合适的位置上,在鼠标点击到对应按键时,将对应按键变色,在处理界面的闪烁过程中使用了双缓冲
void BUTTON::drawbutton(int pos){
int num=b[pos].word.size();
char *C = new char[num+1];
strcpy(C,b[pos].word.c_str());
setfillcolor(b[pos].color);
settextstyle(35,0,"宋体");
settextcolor(BLACK);
setlinecolor(BLACK);
setbkmode(TRANSPARENT);
fillrectangle(b[pos].x,b[pos].y,b[pos].x+b[pos].w,b[pos].y+b[pos].h);
outtextxy(b[pos].x+20,b[pos].y+10,C);
}
bool BUTTON::mouseintbutton(int pos,MOUSEMSG mouse){
if(b[pos].x<=mouse.x&&mouse.x<=b[pos].x+b[pos].w&&b[pos].y<=mouse.y&&mouse.y<=b[pos].y+b[pos].h){
b[pos].color=RED;
return true;
}
return false;
}
int BUTTON::clickbutton(int pos,MOUSEMSG mouse){
if(mouseintbutton(pos,mouse)&&mouse.uMsg==WM_LBUTTONDOWN){
return pos;
}
return -1;
}
最后
文件一m.h头文件:
#ifndef m_H
#define m_H
#pragma once
#include <bits/stdc++.h>
#include <Windows.h>
#include <graphics.h>
#include<easyx.h>
using namespace std;
struct button{//定义交互界面的按钮
int x;
int y;
int w;
int h;
COLORREF color;
string word;
};
struct team{//team类,存储参赛队伍的各种信息
string team_number;//参赛编号
string team_name;//参赛队伍的项目名字
string team_school;//参赛队伍的学校
string team_cateory;//参赛队伍的类别
string team_sutdent;//参赛者
string team_teacher;//指导老师
int score;
};
struct Node{//二叉排序树的节点
int number;//队伍编号
int score;//队伍成绩
Node*lnext;//左节点
Node*rnext;//右节点
};
struct divd{
string cate1;
string cate2;
string cate3;
string cate4;
team t[50];
};
class manager{//赛事管理类
public:
manager();//建表
void change(string str);//改变一个队伍的相关数据,输入的s为队伍的编号
void add();//添加一个队伍
int delete_team(string str);//删除一个队伍的相关数据,输入的str为队伍的编号
team seacher(string str);//查找一个队伍的相关资料
void reset(int pos);//在删除了部分元素后对数组内容的重新划分
void scoreadd();//添加成绩
void print();
int getnum();
team* getnode();
~manager();//析构函数
private:
team t[500];//存数据
int num=0;//记录当前存了多少个队伍
};
class bintree{//二叉排序树的类
public:
bintree(team *t,int num);//建树
Node* insert(Node*bt,team t);//插入节点
void seacher1(Node*p,int k);//查找对应成绩
Node* getroot();//得到根节点
double clc(int x);
void prorder(Node*p,int k);
int getscore();
~bintree();
private:
Node*root;//根节点
int asl;
int score;
};
class competition{//比赛类
public:
competition(team *t,int num);
void sort(divd* s);//排序,插入排序,每次选最大的值入队,时间复杂度为O(n^2);
void swap(team s1,team s2);//交换数据,排序过程中的交换
void comstart();//比赛刚开始
void coming();//比赛中
void comend();//比赛结束
void print();
void seache(string s);
divd* getnode();
~competition();
private:
divd c[17];
bool b[500];
};
class road{//找路类
public:
road();
void seachroad(int s,int e,int*pre);//寻找路径
~road();
};
class BUTTON{
public:
BUTTON();
void drawbutton(int pos);//打印按键
bool mouseintbutton(int pos,MOUSEMSG mouse);//判断鼠标范围
bool clickbutton(int pos,MOUSEMSG mouse);//判断鼠标是否点击
void showdata(team t,int x,int y);//下面几个都是显示数据
void showdata(divd*s,int x,int y);
void showdata(team t);
void showdata(int score,int x,int y);
void win_main(road &r,competition &c,bintree &b,manager &m);//主菜单
void win1(road &r,competition &c,bintree &b,manager &m);//菜单1
void win2(road &r,competition &c,bintree &b,manager &m);//菜单2
void win3(road &r,competition &c,bintree &b,manager &m);//菜单3
void win4(road &r,competition &c,bintree &b,manager &m);
void turnpage(road &r,competition &c,bintree &b,manager &m,int page);//翻页
void showqueue(road &r,competition &c,bintree &b,manager &m,int page);//显示队伍
void drawmapbutton(int pos,int b);//绘制地图按键
private:
button b[20];
button m[17];
};
#endif
文件二:m.cpp,类函数的实现
#include "m.h"
#include <unistd.h>
#include <graphics.h>
#include <bits/stdc++.h>
#include <Windows.h>
#include <bits/stdc++.h>
#include <conio.h>
#include <easyx.h>
using namespace std;
string char_to_string(char *C){
string s;
for(int i=0;;i++){
if(!C[i]){
break;
}
s+=C[i];
}
return s;
}
int char_to_int(char *c){
int s;
int num=0;
for(int i=0;;i++){
if(!c[i]){
break;
}
num++;
}
num-=1;
for(int i=0;;i++){
if(!c[i]){
break;
}
s+=(c[i]-'0')*pow(10,num);
num--;
}
return s;
}
manager::manager(){//管理类的构造函数
ifstream readfile;
readfile.open("team.txt",ios::in);//读出文件数据
if(readfile.is_open()){
char s;
string s1;
int i=0;//记录已读的行数
int b=0;//记录当前需要存储的数据类型
while((s=readfile.get())!=EOF){
if(s=='\n'){
b=0;
i++;
}
if(s=='#'){
b++;
}
if(s!='\0'&&s!='\t'&&s!='#'&&s!='\n'){
if(b==0){
t[i].team_number+=s;
}else if(b==1){
t[i].team_name+=s;
}else if(b==2){
t[i].team_school+=s;
}else if(b==3){
t[i].team_cateory+=s;
}else if(b==4){
t[i].team_sutdent+=s;
}else if(b==5){
t[i].team_teacher+=s;
}
}
}
num=i;
}
readfile.close();
}
team manager::seacher(string s){//查找队伍
for(int i=1;i<=num;i++){
if(t[i].team_number==s){
return t[i];
}
}
}
//void manager::change(string s){
// team m=seacher(s);
//
//}
void manager::add(){//添加队伍
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
ofstream ofs;
char s[20];
string str;
ofs.open("team.txt",ios::app);
num++;
InputBox(s,20,"请输入队伍的编号",NULL,0,0,true);
str=char_to_string(s);
t[num].team_number=str;
InputBox(s,20,"请输入队伍项目名称",NULL,0,0,true);
str=char_to_string(s);
t[num].team_name=str;
InputBox(s,20,"请输入队伍学校",NULL,0,0,true);
str=char_to_string(s);
t[num].team_school=str;
InputBox(s,20,"请输入队伍项目类别",NULL,0,0,true);
str=char_to_string(s);
t[num].team_cateory=str;
InputBox(s,20,"请输入队伍学生",NULL,0,0,true);
str=char_to_string(s);
t[num].team_sutdent=str;
InputBox(s,20,"请输入队伍老师",NULL,0,0,true);
str=char_to_string(s);
t[num].team_teacher=str;
ofs<<t[num].team_number<<"\t"<<"#"<<"\t"<<t[num].team_name<<"\t"<<"#"<<"\t"<<t[num].team_school<<"\t"<<"#"<<"\t"<<t[num].team_cateory<<"\t"<<"#"<<"\t"<<t[num].team_sutdent<<"\t"<<"#"<<"\t"<<t[num].team_teacher<<"\n";
ofs.close();
setfillcolor(YELLOW);
settextcolor(BLACK);
setlinecolor(BLACK);
settextstyle(50,0,"宋体");
setbkmode(TRANSPARENT);
outtextxy(300,300,"添加完成");
system("cls");
}
int manager::getnum(){//得到当前已存的队伍数
return num;
}
team* manager::getnode(){//得到team类的数组
return t;
}
void manager::print(){//浏览已经存在的队伍
for(int i=0;i<num;i++){
cout<<t[i].team_cateory<<"\n";//change
}
sleep(8);
}
void manager::scoreadd(){//添加成绩
srand((int)time(NULL));//随机数生成
for(int i=1;i<=num;i++){
t[i].score=rand()%41+60;
}
}
void manager::reset(int pos){//在删除或修改了部分元素后对其重新划分
for(int i=pos;i<num;i++){
t[i].score=t[i+1].score;
t[i].team_cateory=t[i+1].team_cateory;
t[i].team_name=t[i+1].team_name;
t[i].team_school=t[i+1].team_school;
t[i].team_sutdent=t[i+1].team_sutdent;
t[i].team_number=t[i+1].team_number;
t[i].team_teacher=t[i+1].team_teacher;
}
t[num]={0};
}
int manager::delete_team(string str){//队伍删除
ifstream readfile;
readfile.open("team1.txt",ios::in);//读出文件数据
int linenum=1;//记录所找数据在第几行
if(readfile.is_open()){
char s;
string s1;
while((s=readfile.get())!=EOF){
if(s=='\n'){
s1="";
linenum++;
}
if(s!='\0'&&s!='\t'&&s!='#'&&s!='\n'){
s1+=s;
if(s1==str){
break;
}
}
}
}
if(linenum==num+1){
cout<<"改队伍已删除";
return -1;
}
readfile.close();
ofstream ofs;
ofs.open("team1.txt",ios::out);
int b=1;
int pos=0;
while(pos!=num){
if(pos!=linenum-1){
ofs<<t[pos].team_number<<"\t"<<"#"<<"\t"<<t[pos].team_name<<"\t"<<"#"<<"\t"<<t[pos].team_school<<"\t"<<"#"<<"\t"<<t[pos].team_cateory<<"\t"<<"#"<<"\t"<<t[pos].team_sutdent<<"\t"<<"#"<<"\t"<<t[pos].team_teacher<<"\n";
}
pos++;
}
reset(linenum);
ofs.close();
sleep(8);
system("cls");
return pos;
}
void manager::change(string str){//队伍修改
ifstream readfile;
readfile.open("team1.txt",ios::in);//读出文件数据
int linenum=1;//记录所找数据在第几行
if(readfile.is_open()){
char s;
string s1;
while((s=readfile.get())!=EOF){
if(s=='\n'){
s1="";
linenum++;
}
if(s!='\0'&&s!='\t'&&s!='#'&&s!='\n'){
s1+=s;
if(s1==str){
break;
}
}
}
}
if(linenum==num+1){
cout<<"改队伍已删除";
return ;
}
readfile.close();
ofstream ofs;
ofs.open("team1.txt",ios::out);
int b=1;
int pos=0;
while(pos!=num){
if(pos!=linenum-1){
cout<<"please reset the sat"<<"\n" ;
cout<<"请输入队伍编号"<<"\n";
cin>>t[pos].team_number;
cout<<"请输入队伍项目名称"<<"\n";
cin>>t[pos].team_name;
cout<<"请输入队伍学校"<<"\n";
cin>>t[pos].team_school;
cout<<"请输入队伍项目类别"<<"\n";
cin>>t[pos].team_cateory;
cout<<"请输入队伍参赛队员与指导老师"<<"\n";
cin>>t[pos].team_sutdent>>t[pos].team_teacher;
ofs<<t[pos].team_number<<"\t"<<"#"<<"\t"<<t[pos].team_name<<"\t"<<"#"<<"\t"<<t[pos].team_school<<"\t"<<"#"<<"\t"<<t[pos].team_cateory<<"\t"<<"#"<<"\t"<<t[pos].team_sutdent<<"\t"<<"#"<<"\t"<<t[pos].team_teacher<<"\n";
pos++;
continue;
}
ofs<<t[pos].team_number<<"\t"<<"#"<<"\t"<<t[pos].team_name<<"\t"<<"#"<<"\t"<<t[pos].team_school<<"\t"<<"#"<<"\t"<<t[pos].team_cateory<<"\t"<<"#"<<"\t"<<t[pos].team_sutdent<<"\t"<<"#"<<"\t"<<t[pos].team_teacher<<"\n";
pos++;
}
ofs.close();
system("cls");
}
bintree::bintree(team *t,int num){//构造二叉排序树
root=NULL;
for(int i=1;i<=num;i++){
root=insert(root,t[i]);
}
}
Node* bintree::insert(Node*bt,team t){//插入二叉排序树的节点
string s1;
bool b=false;
for(int i=5;i<=10;i++){
if(t.team_number[i]!='0'){
b=true;
}
if(b){
s1+=t.team_number[i];
}
}
int str=atoi(s1.c_str());//保留后6位中的数字大小
if(bt==NULL){
Node*s=new Node;
s->number=str;
s->score=t.score;
s->lnext=s->rnext=NULL;
bt=s;
return bt;
}else if(bt->number>str){
bt->lnext=insert(bt->lnext,t);
}else {
bt->rnext=insert(bt->rnext,t);
}
return bt;
}
void bintree::seacher1(Node*p,int k){//查找对应编号的成绩
if(p==NULL){
return ;
}
if(p->number==k){
int num=p->score;
char *C=new char[2];
string str=to_string(num);
strcpy(C,str.c_str());
setfillcolor(YELLOW);
settextcolor(BLACK);
setlinecolor(BLACK);
settextstyle(100,0,"宋体");
setbkmode(TRANSPARENT);
outtextxy(0,0,C);
}
seacher1(p->lnext,k);
seacher1(p->rnext,k);
}
int bintree::getscore(){
return score;
}
Node* bintree::getroot(){//外部得到二叉排序树的根节点
return root;
}
void bintree::prorder(Node*p,int k){//遍历平衡二叉树,并计算asl
if(p==NULL){
return ;
}
asl+=1*k;
prorder(p->lnext,++k);
prorder(p->rnext,++k);
}
double bintree::clc(int x){
return asl/x;
}
competition::competition(team *t,int num){
c[0].cate1="大数据实践";
c[0].cate2="信息图形设计";
c[1].cate1="动态信息影像(MG动画)";
c[1].cate2="交互信息设计";
c[1].cate3="数据可视化";
c[2].cate1="人工智能实践赛";
c[3].cate1="人工智能实践赛";
c[4].cate1="Web应用与开发";
c[4].cate2="管理信息系统";
c[5].cate1="算法设计与应用";
c[6].cate1="移动应用开发";
c[6].cate2="医药卫生";
c[7].cate1="数字生活";
c[7].cate2="运动健身";
c[7].cate3="行业应用";
c[7].cate4="城市管理";
c[8].cate1="动画";
c[8].cate2="纪录片";
c[9].cate1="微电影";
c[9].cate2="新媒体漫画";
c[10].cate1="环境设计";
c[10].cate2="产品设计";
c[11].cate1="平面设计";
c[12].cate1="交互媒体设计";
c[12].cate2="游戏设计";
c[12].cate3="虚拟现实VR与增强现实AR";
c[13].cate1="汉语言文学";
c[13].cate2="计算机基础与应用类课程微课";
c[14].cate1="虚拟实验平台";
c[15].cate1="中、小学数学或自然科学课程微课";
for(int i=0;i<=16;i++){
int pos=0;
cout<<"\n";
for(int j=1;j<=num;j++){
if(i==16&&!b[j]){
c[i].t[pos++]=t[j];
// cout<<j<<"\n";
b[j]=true;
continue;
}
if(pos>24&&!b[j]){
continue;
}
if(t[j].team_cateory==c[i].cate1&&!b[j]){
b[j]=true;
c[i].t[pos++]=t[j];
}else if(t[j].team_cateory==c[i].cate2&&!b[j]){
b[j]=true;
c[i].t[pos++]=t[j];
}else if(t[j].team_cateory==c[i].cate3&&!b[j]){
b[j]=true;
c[i].t[pos++]=t[j];
}else if(t[j].team_cateory==c[i].cate4&&!b[j]){
b[j]=true;
c[i].t[pos++]=t[j];
}
}
}
}
void competition::print(){//打印所有队伍
int x=0;
for(int i=0;i<17;i++){
int pos=0;
while(c[i].t[pos].team_number!=""){
cout<<c[i].t[pos].team_cateory<<"\n";
pos++;
}
}
}
void competition::swap(team s1,team s2){
team t;
t=s1;
s1=s2;
s2=t;
}
void competition::sort(divd* s){//将17个队伍中的成绩排序
for(int j1=0;j1<=16;j1++){
for(int i=0;;i++){
if(s[j1].t[i].score==0){
break;
}
for(int j=0;;j++){
if(s[j1].t[j].score==0){
break;
}
if(s[j1].t[i].score<s[j1].t[j].score){
swap(s[j1].t[i],s[j1].t[j]);
}
}
}
}
}
void competition::comstart(){//比赛刚开始,后面界面没搞这个,感觉没意思
cout<<"competition is ready"<<"\n";
cout<<"welcome to this play"<<"\n";
}
void competition::coming(){//控制台版本的队伍动态展示
for(int i=0;;i++){
cout<<c[0].t[i].team_name<<" ing\n";
cout<<c[1].t[i].team_name<<" ing\n";
cout<<c[2].t[i].team_name<<" ing\n";
cout<<c[3].t[i].team_name<<" ing\n";
cout<<c[4].t[i].team_name<<" ing\n";
cout<<c[5].t[i].team_name<<" ing\n";
cout<<c[6].t[i].team_name<<" ing\n";
cout<<c[7].t[i].team_name<<" ing\n";
cout<<c[8].t[i].team_name<<" ing\n";
cout<<c[9].t[i].team_name<<" ing\n";
cout<<c[10].t[i].team_name<<" ing\n";
cout<<c[11].t[i].team_name<<" ing\n";
cout<<c[12].t[i].team_name<<" ing\n";
cout<<c[13].t[i].team_name<<" ing\n";
cout<<c[14].t[i].team_name<<" ing\n";
cout<<c[15].t[i].team_name<<" ing\n";
cout<<c[16].t[i].team_name<<" ing\n";
sleep(5);
cout<<"请下一队上前"<<"\n";
sleep(2);
system("cls");
}
}
void competition::seache(string s){
for(int i=0;i<=16;i++){
int pos=0;
while(c[i].t[pos].team_number!=""){
if(c[i].t[pos].team_number==s){
char *c=new char[2];
string str=to_string(i+1);
strcpy(c,str.c_str());
setfillcolor(YELLOW);
settextcolor(BLACK);
setlinecolor(BLACK);
settextstyle(100,0,"宋体");
setbkmode(TRANSPARENT);
outtextxy(0,0,c);
}
pos++;
}
}
}
void competition::comend(){
cout<<"play is over"<<"\n";
}
road::road(){
return ;
}
BUTTON::BUTTON(){//初始化地图按键和按键
string str[17]={//?
"赛前准备",
"决赛开始",
"校园导航",
"查询队伍",
"修改队伍",
"删除队伍",
"添加队伍",
"查询初赛成绩",
"查询所有队伍",
"查询决赛分组",
"比赛进度-开始阶段",
"比赛进度-中途阶段",
"比赛进度-结束阶段",
"返回",
"下一页",
"退出",
"上一页",
};
int x=300;
int y=150;
int w=180;
int h=50;
COLORREF color=YELLOW;
for(int i=0;i<3;i++){//初始化按键
b[i].x=x;
b[i].y=y;
b[i].w=w;
b[i].h=h;
y+=80;
b[i].color=color;
b[i].word=str[i];
}
y=50;
for(int i=3;i<9;i++){
b[i].x=x;
b[i].y=y;
b[i].w=w;
b[i].h=h;
y+=80;
if(i==7){
w=270;
x=255;
}
b[i].color=color;
b[i].word=str[i];
}
y=100;x=300;w=180;
for(int i=9;i<13;i++){
if(i==10){
w=360;
x=210;
}
b[i].x=x;
b[i].y=y;
b[i].w=w;
b[i].h=h;
y+=80;
b[i].color=color;
b[i].word=str[i];
}
x=500;
y=500;
w=180;
h=50;
b[13].h=h;b[13].w=w;b[13].word=str[13];b[13].x=x;b[13].y=y;b[13].color=color;
b[14].h=h;b[14].w=150;b[14].word=str[14];b[14].x=300;b[14].y=y;b[14].color=color;
b[15].h=h;b[15].w=w;b[15].word=str[15];b[15].x=x;b[15].y=y;b[15].color=color;
b[16].h=h;b[16].w=150;b[16].word=str[16];b[16].x=0;b[16].y=y;b[16].color=color;
color=RED;
w=10,h=10;
for(int i=0;i<17;i++){
m[i].h=h;
m[i].w=w;
m[i].color=color;
}//初始化地图按键,n-n为其经过的点
m[0].x=600,m[0].y=70;//1-2
m[1].x=650,m[1].y=200;//2-3
m[2].x=650,m[2].y=300;//3-4
m[3].x=650,m[3].y=400;//4-5
m[4].x=550,m[4].y=250;//10-3
m[5].x=550,m[5].y=300;//8-3
m[6].x=550,m[6].y=400;//7-4
m[7].x=550,m[7].y=550;//6-5
m[8].x=500,m[8].y=150;//10-1
m[9].x=400,m[9].y=250;//10-9
m[10].x=400,m[10].y=330;//9-8
m[11].x=300,m[11].y=400;//11-8
m[12].x=300,m[12].y=450;//11-7
m[13].x=300,m[13].y=500;//12-8
m[14].x=150,m[14].y=450;//12-11
m[15].x=400,m[15].y=400;//8-7
m[16].x=470,m[16].y=500;//6-7
}
void BUTTON::drawmapbutton(int pos,int b){//绘制地图按键
if(b==0){
setfillcolor(m[pos].color);
}else{
setfillcolor(GREEN);
}
setlinecolor(BLACK);
setbkmode(TRANSPARENT);
fillrectangle(m[pos].x,m[pos].y,m[pos].x+m[pos].w,m[pos].y+m[pos].h);
}
void BUTTON::drawbutton(int pos){//绘制按键
int num=b[pos].word.size();
char *C = new char[num+1];
strcpy(C,b[pos].word.c_str());
setfillcolor(b[pos].color);
settextstyle(35,0,"宋体");
settextcolor(BLACK);
setlinecolor(BLACK);
setbkmode(TRANSPARENT);
fillrectangle(b[pos].x,b[pos].y,b[pos].x+b[pos].w,b[pos].y+b[pos].h);
outtextxy(b[pos].x+20,b[pos].y+10,C);
}
bool BUTTON::mouseintbutton(int pos,MOUSEMSG mouse){//检测鼠标点击的范围
if(b[pos].x<=mouse.x&&mouse.x<=b[pos].x+b[pos].w&&b[pos].y<=mouse.y&&mouse.y<=b[pos].y+b[pos].h){
// b[pos].color=RED;
return true;
}
// b[pos].color=YELLOW;
return false;
}
void BUTTON::showdata(int score,int x,int y){//展示int类型的数据
char *C=new char[2];
string str=to_string(score);
strcpy(C,str.c_str());
setfillcolor(YELLOW);
settextcolor(BLACK);
setlinecolor(BLACK);
settextstyle(100,0,"宋体");
setbkmode(TRANSPARENT);
outtextxy(x,y,C);
}
void BUTTON::showdata(team t,int x,int y){//忘了是干啥的了 ,展示team类型的数据中的项目名字
int num=t.team_name.size();
char *C = new char[num+1];
strcpy(C,t.team_name.c_str());
setfillcolor(YELLOW);
settextcolor(BLACK);
setlinecolor(BLACK);
settextstyle(15,0,"宋体");
setbkmode(TRANSPARENT);
outtextxy(x,y,C);
}
bool BUTTON::clickbutton(int pos,MOUSEMSG mouse){//检测鼠标点击
if(mouseintbutton(pos,mouse)&&mouse.uMsg==WM_LBUTTONDOWN){
return true;
}
return false;
}
void BUTTON::win_main(road &r,competition &c,bintree &b,manager &m){//主界面
// initgraph(800,600);
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
for(int i=0;i<3;i++){
drawbutton(i);
}
drawbutton(15);
while (1) {
BeginBatchDraw();
MOUSEMSG mm = GetMouseMsg();
if(clickbutton(0,mm)){//界面赛前准备
win1(r,c,b,m);
}
if(clickbutton(1,mm)){//决赛开始
win2(r,c,b,m);
}
if(clickbutton(2,mm)){//校园导航
win3(r,c,b,m);
}
if(clickbutton(15,mm)){
closegraph();
}
EndBatchDraw();
}
_getch();
closegraph();
return ;
}
void BUTTON::showdata(team t){//展现查询的队伍的基本信息
int num[7];
num[1]=t.team_name.size();
num[2]=t.team_cateory.size();
num[0]=t.team_number.size();
num[3]=t.team_school.size();
num[4]=t.team_sutdent.size();
num[5]=t.team_teacher.size();
int y=0;
for(int i=0;i<6;i++){
char *C = new char[num[i]+1];
if(i==1){
strcpy(C,t.team_name.c_str());
}
if(i==2){
strcpy(C,t.team_cateory.c_str());
}
if(i==0){
strcpy(C,t.team_number.c_str());
}
if(i==3){
strcpy(C,t.team_school.c_str());
}
if(i==4){
strcpy(C,t.team_sutdent.c_str());
}
if(i==5){
strcpy(C,t.team_teacher.c_str());
}
setfillcolor(YELLOW);
settextcolor(BLACK);
setlinecolor(BLACK);
settextstyle(15,0,"宋体");
setbkmode(TRANSPARENT);
outtextxy(0,y,C);
y+=30;
}
}
divd* competition::getnode(){
return c;
}
void BUTTON::showdata(divd *s,int x,int y ){//展示17个参赛队伍的人
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
int pos=0;
for(int i=0;i<17;i++){
string str=s[i].t[y].team_name;
int num=str.size();
if(str==""){
continue;
}
char *C = new char[num+1];
strcpy(C,str.c_str());
setfillcolor(YELLOW);
settextcolor(BLACK);
setlinecolor(BLACK);
settextstyle(15,0,"宋体");
setbkmode(TRANSPARENT);
outtextxy(0,pos,C);
pos+=30;
}
// srand((int)time(NULL));
// int x1=rand()%1+4;
}
void BUTTON::showqueue(road &r,competition &c,bintree &b,manager &m,int page){//展示17个参赛队伍
divd*s=c.getnode();
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
page+=1;
showdata(s,0,page);
while(1){
sleep(5);
BeginBatchDraw();
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
page++;
showdata(s,0,page);
if(page==25){
win2(r,c,b,m);
}
EndBatchDraw();
}
}
void BUTTON::turnpage(road &r,competition &c,bintree &b,manager &m,int page){//翻页,page记录当前的页面
team*t=m.getnode();
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
showdata(t[0],0,0);
int x=0,y=30;
for(int i=page*16+1;i<=(page+1)*16;i++){
showdata(t[i],x,y);
y+=30;
}
if(page*16<=m.getnum()){
drawbutton(16);drawbutton(14);
}else{
drawbutton(13);
}
while(1){
BeginBatchDraw();
MOUSEMSG mm = GetMouseMsg();
if(clickbutton(16,mm)&&page==1){
win1(r,c,b,m);
}
if(clickbutton(16,mm)&&page!=1){
page-=1;
turnpage(r,c,b,m,page);
}
if(clickbutton(14,mm)){
page+=1;
turnpage(r,c,b,m,page);
}
if(clickbutton(13,mm)){
win1(r,c,b,m);
}
EndBatchDraw();
}
return ;
}
void BUTTON::win1(road &r,competition &c,bintree &b,manager &m){//界面赛前准备
// initgraph(800, 600);
team*t=m.getnode();
IMAGE p;
int page=0;
int page1=0;
int pos;
int k;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
for(int i=3;i<9;i++){
drawbutton(i);
}
char s[20];
string str;
drawbutton(13);
while(1){
BeginBatchDraw();
MOUSEMSG mm = GetMouseMsg();
if(clickbutton(3,mm)){//查询队伍
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
InputBox(s,20,"请输入查询队伍的编号",NULL,0,0,true);
str=char_to_string(s);
team t_s=m.seacher(str);
showdata(t_s);
drawbutton(13);
page=1;
}
if(clickbutton(4,mm)){//修改队伍
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
drawbutton(13);
page=1;
}
if(clickbutton(5,mm)){//删除队伍
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
InputBox(s,20,"请输入删除队伍的编号",NULL,0,0,true);
str=char_to_string(s);
pos=m.delete_team(str);
m.reset(pos);
setfillcolor(YELLOW);
settextcolor(BLACK);
setlinecolor(BLACK);
settextstyle(50,0,"宋体");
setbkmode(TRANSPARENT);
outtextxy(300,300,"已删除");
drawbutton(13);
page=1;
}
if(clickbutton(6,mm)){//添加队伍
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
m.add();
drawbutton(13);
page=1;
}
if(clickbutton(7,mm)){//查询初赛成绩
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
InputBox(s,6,"请输入查询队伍后六位有效数字的编号",NULL,0,0,true);
k=char_to_int(s);
b.seacher1(b.getroot(),k);
b.prorder(b.getroot(),0);
int asl_f=b.clc(m.getnum());
showdata(asl_f,300,200);
drawbutton(13);
page=1;
}
if(clickbutton(8,mm)){//查询所有队伍
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
int num=m.getnum();int x=0,y=30;
showdata(t[0],0,0);
for(int i=1;i<=16;i++){
showdata(t[i],x,y);
y+=30;
}
drawbutton(14);
drawbutton(13);
page1+=1;
page=1;
}
if(clickbutton(14,mm)){
turnpage(r,c,b,m,page1);
}
if(clickbutton(13,mm)&&page==0){
win_main(r,c,b,m);
}
if(clickbutton(13,mm)&&page==1){
win1(r,c,b,m);
}
EndBatchDraw();
}
return ;
}
void BUTTON::win2(road &r,competition &c,bintree &b,manager &m){//决赛开始
// initgraph(800, 600);
int page=0;
int page2=0;
char s[20];
divd*S=c.getnode();
string str;
team*t=m.getnode();
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
for(int i=9;i<13;i++){
drawbutton(i);
}
drawbutton(13);
while(1){
BeginBatchDraw();
MOUSEMSG mm = GetMouseMsg();
if(clickbutton(9,mm)){//查询队伍
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
InputBox(s,20,"请输入查询队伍的编号",NULL,0,0,true);
str=char_to_string(s);
c.seache(str);
drawbutton(13);
page=1;
}
if(clickbutton(10,mm)){//比赛前
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
drawbutton(13);
page=1;
}
if(clickbutton(11,mm)){//比赛中
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
showdata(S,0,page2);
drawbutton(13);
page2=1;
page=1;
}
if(clickbutton(12,mm)){//比赛后
IMAGE p;
loadimage(&p,_T("2.jpg"),800,600);
putimage(0,0,&p);
drawbutton(13);
page=1;
}
if(clickbutton(13,mm)&&page==0){
win_main(r,c,b,m);
}
if(clickbutton(13,mm)&&page==1){
win2(r,c,b,m);
}
if(page2!=0){//当开进行比赛时的进程
showqueue(r,c,b,m,page2);
page2=0;
}
EndBatchDraw();
}
return ;
}
void BUTTON::win3(road &r,competition &c,bintree &b,manager &m){//校园导航
// initgraph(800, 600);
team*t=m.getnode();
IMAGE p;
loadimage(&p,_T("1.jpg"),800,600);
putimage(0,0,&p);
drawbutton(13);
char s1[2];
char s2[2];
int s,e;
int pre[13];
InputBox(s1,3,"请输入起点编号",NULL,0,0,true);
InputBox(s2,3,"请输入终点编号",NULL,0,0,true);
s=s1[0]-'0';
e=s2[0]-'0';
r.seachroad(s,e,pre);
for(int i=0;i<17;i++){
drawmapbutton(i,0);
}
for(int i = 13; i > 1; i--)//n 个节点,所以有 n-1 条边。
{
if((i==1&&pre[i]==2)||(pre[i]==1&&i==2))drawmapbutton(0,1);
if((i==3&&pre[i]==2)||(pre[i]==3&&i==2))drawmapbutton(1,1);
if((i==3&&pre[i]==4)||(pre[i]==3&&i==4))drawmapbutton(2,1);
if((i==4&&pre[i]==5)||(pre[i]==4&&i==5))drawmapbutton(3,1);
if((i==10&&pre[i]==3)||(pre[i]==10&&i==3))drawmapbutton(4,1);
if((i==8&&pre[i]==3)||(pre[i]==8&&i==3))drawmapbutton(5,1);
if((i==7&&pre[i]==4)||(pre[i]==7&&i==4))drawmapbutton(6,1);
if((i==6&&pre[i]==5)||(pre[i]==6&&i==5))drawmapbutton(7,1);
if((i==10&&pre[i]==1)||(pre[i]==10&&i==1))drawmapbutton(8,1);
if((i==10&&pre[i]==9)||(pre[i]==10&&i==9))drawmapbutton(9,1);
if((i==9&&pre[i]==8)||(pre[i]==9&&i==8))drawmapbutton(10,1);
if((i==11&&pre[i]==8)||(pre[i]==11&&i==8))drawmapbutton(11,1);
if((i==11&&pre[i]==7)||(pre[i]==11&&i==7))drawmapbutton(12,1);
if((i==12&&pre[i]==8)||(pre[i]==12&&i==8))drawmapbutton(13,1);
if((i==12&&pre[i]==11)||(pre[i]==12&&i==11))drawmapbutton(14,1);
if((i==8&&pre[i]==7)||(pre[i]==8&&i==7))drawmapbutton(15,1);
if((i==7&&pre[i]==6)||(pre[i]==7&&i==6))drawmapbutton(16,1);
}//打印到各点的最短路的经过点
while(1){
BeginBatchDraw();
MOUSEMSG mm = GetMouseMsg();
if(clickbutton(13,mm)){
win_main(r,c,b,m);//当鼠标到返回健时回到主菜单
}
EndBatchDraw();
}
return ;
}
void road::seachroad(int s,int e,int*pre){//寻路算法,基于dijkstra
int g[13][13];
int n=12, m=17;
int dist[13]; // 每个点到起点的距离
bool st[13]; // 是否已经确定了最短路径
memset(g,0x3f3f3f,sizeof(g));
g[1][2]=g[2][1]=300;//构建无向图
g[2][3]=g[3][2]=600;
g[3][4]=g[4][3]=100;
g[4][5]=g[5][4]=100;
g[5][6]=g[6][5]=100;
g[7][6]=g[6][7]=250;
g[7][8]=g[8][7]=100;
g[8][9]=g[9][8]=100;
g[10][9]=g[9][10]=100;
g[1][10]=g[10][1]=700;
g[10][3]=g[3][10]=400;
g[3][8]=g[8][3]=450;
g[4][7]=g[7][4]=550;
g[8][11]=g[11][8]=250;
g[11][7]=g[7][11]=300;
g[11][12]=g[12][11]=200;
g[12][6]=g[6][12]=700;
memset(dist, 0x3f, sizeof dist);
dist[s] = 0;
for (int i = 1; i <= n; i ++ )
{
int t = 0; // 结点从1开始,所以0作为记录最近点的初始化
for (int j = 1; j <= n; j ++) // 遍历点,若一个点 j 满足:1.未确定最短距离 2.比现有的最近点更近
if (!st[j] && dist[j] < dist[t])
t = j;
st[t] = true; // 将找到的最近点的状态改为已确定
for (int j = 1; j <= n; j ++ )
{
if (dist[j] > dist[t] + g[t][j])
{
dist[j] = dist[t] + g[t][j]; // 以找到的最近点t,更新所有其它点的距离
pre[j] = t; // 如果以t点更像了j点的距离,则t->j是一条最短路
}
}
} //最短路
int num=dist[e];
string str=to_string(num);
char *C=new char[str.size()+1];
strcpy(C,str.c_str());
settextcolor(BLACK);
setlinecolor(BLACK);
settextstyle(35,0,"宋体");
setbkmode(TRANSPARENT);
outtextxy(0,0,C);//打印最短距离
}
competition::~competition(){
return ;
}
manager::~manager(){//析构函数
return ;
}
bintree::~bintree(){
return ;
}
road::~road(){
return ;
}
文件三,主函数
#include "m.h"
#include <graphics.h>
#include <Windows.h>
#include <bits/stdc++.h>
#include <easyx.h>
using namespace std;
int main(){
manager m;
m.scoreadd();
bintree b(m.getnode(),m.getnum());
competition c(m.getnode(),m.getnum());
BUTTON bu;
road r;
initgraph(800,600);
bu.win_main(r,c,b,m);
closegraph();
return 1;
}