程序设计与数据结构课程实训报告——回家之旅

回家之旅
1.问题描述
春运买票困难,有乘客想出多次中转的办法解决。试图用你学习到的数据结构与算法知识,帮助有需要的人规划回家的路线。
假设给定列车时刻信息表(包含票价情况),任意输入起点站和终点站(如广州到兰州),规划满足以下一种或者同时满足多种目标的乘车方案:
目标1:换乘次数最少【中间节点数最少的情况】;
目标2:预计耗费时间最短【让两个站点时间总加】;
目标3:票价总和最小;
目标4:卧铺优先【设置软铺、硬铺和硬座三种价格】;
目标5:错过换乘的可能性最小(因为存在晚点的可能,需考虑最短的理论换乘时间)

2.基本要求
(1)为简化相关算法,可以对问题做出一些假设,如:
简化全国的运营线路图,即改为足够多的局部的运营线路图;
对每个站点,任何一天的列车启停的情况都一样;
不考虑无票情况
(2)根据实际问题进行合理详细的需求分析
(3)功能模块划分至少包含:
输入、输出模块
数据操纵模块:如添加、修改或者删除线路、站点信息等
查询功能模块:如查询线路的相关信息
预处理模块

这篇报告是我和我的两个队友一起做的,大家认为可以打多少分,可以在评论区留言,谢谢!

#include <iostream>
#include<map>
#include<algorithm>
#include<set>
#include<vector>
#include<math.h>
#include<string>
#include<fstream>
using namespace std;
#define int long long
const int mintransfertime = 15; //理论换乘时间,以分钟为单位
const int INF = 0x3f3f3f3f; //无穷大
const string USER_PASSWORD = "654321", MANAGER_PASSWORD = "123456";
bool flag, tag, mark;
// 定义一个结构体,表示一趟列车的信息
struct Train
{string id; //列车编号string from; //起点站string to; //终点站int depart; //出发时间,以分钟为单位int arrive; //到达时间,以分钟为单位int soft; //软卧票价int hard; //硬卧票价int seat; //硬座票价
};
// 定义一个结构体,表示一条乘车方案
struct Plan
{vector <Train> trains; //包含的列车列表int cost; //总票价int time; //总耗时int transfer; //换乘次数int soft_cnt;//软卧的数量int hard_cnt;//硬卧的数量int seat_cnt;//硬座的数量
};
// 定义一个函数,将分钟转换为时钟格式
string format(int minutes)
{int hour = minutes / 60;//将分钟化为小时int minute = minutes % 60;//取模60剩下的就是分钟数string result = "";if (hour < 10) result += "0";result += to_string(hour) + ":";//将int转化为stringif (minute < 10) result += "0";//补齐两位result += to_string(minute);//加上分钟return result;
}
// 定义一个函数,输出一条乘车方案的详细信息
void printPlan(Plan plan)
{cout << "总票价:" << plan.cost << "元" << endl;cout << "总耗时:" << format(plan.time) << endl;cout << "换乘次数:" << plan.transfer << endl;cout << "乘车详情:" << endl;for (int i = 0; i < plan.trains.size(); i++)//plan里面的所有乘车计划打印出来{Train train = plan.trains[i];cout << train.id << " " << train.from << " " << format(train.depart) << " -> " << train.to << " " << format(train.arrive) << endl;}
}
// 定义一个函数,比较两条乘车方案,返回较优的方案
// 优先级:总耗时>总票价>换乘次数>卧铺优先(软卧>硬卧>硬座)
Plan compare(Plan p1, Plan p2)
{if (p1.time < p2.time) return p1;//先比价两条路线的总耗时if (p1.time > p2.time) return p2;if (p1.cost < p2.cost) return p1;//如果时间相同比较两条路线的总花费if (p1.cost > p2.cost) return p2;if (p1.transfer < p2.transfer) return p1;//在时间花费相同的情况下,比较换乘次数if (p1.transfer > p2.transfer) return p2;if (p1.soft_cnt < p2.soft_cnt)return p1;//在以上条件都相同的情况下,比较软卧,硬卧,硬座的数量if (p1.soft_cnt > p2.soft_cnt)return p2;if (p1.hard_cnt < p2.seat_cnt)return p1;if (p1.hard_cnt > p2.seat_cnt)return p2;if (p1.seat_cnt <= p2.seat_cnt)return p1;elsereturn p2;
}
vector <Train> timeable; //表示列车时刻信息表
vector <string> stations; //表示站点的集合
map <string, vector<Train>> adj; //表示站点之间的邻近表
//定义一个函数,初始化全局变量
void init()
{// 以下是示例数据,可以根据实际情况进行修改或者从文件中读取string s;string data[1010];//data用来暂时存储txt读出的数据ifstream infile;infile.open("d:\\out.txt", ios::in);if (!infile.is_open())//判断文件是否读取成功{cout << "文件读取失败" << endl;return;}vector<string>t;while (getline(infile, s)){s += " ";//在末尾也加上空格,保证了数据不会漏掉int pre = 0, cnt = 0;for (int i = 0; i < s.size(); i++){if (s[i] == ' ')//以空格为分隔符进行数据分割{data[++cnt] = s.substr(pre, i - pre);//用substr函数来辅助进行分割pre = i + 1;//这里加一就跳过了空格,包正了数据的正确}}timeable.push_back({ data[1],data[2],data[3],stoi(data[4]),stoi(data[5]),stoi(data[6]),stoi(data[7]),stoi(data[8]) });}infile.close();//遍历时刻表,构建站点集合和邻接表for (int i = 0; i < timeable.size(); i++){Train train = timeable[i];if (find(stations.begin(), stations.end(), train.from) == stations.end()){stations.push_back(train.from); //起点站不在站点集合中,就添加进去}if (find(stations.begin(), stations.end(), train.to) == stations.end()){stations.push_back(train.to); //终点站不在站点集合中,就添加进去}if (adj.find(train.from) == adj.end()){adj[train.from] = vector<Train>(); //起点站不在邻接表,就添加一个空的邻接表项}adj[train.from].push_back(train);}
}
//定义一个函数,进行深度优先搜索,寻找最优的乘车方案
void dfs(string start, string endp, Plan& best, Plan& current, vector<string>& visited)
{//如果当前站点是终点站,就比较当前方案和最优方案,更新最优方案if (start == endp){best = compare(best, current);return;}//如果当前站点已经访问过,就返回if (find(visited.begin(), visited.end(), start) != visited.end()){return;}//将当前站点标记为已访问visited.push_back(start);//遍历当前站点的邻接表,尝试所有可能的下一趟列车for (int i = 0; i < adj[start].size(); i++){Train train = adj[start][i];//如果当前方案为空,或者当前方案的最后一趟列车的到达时间加上最短换乘时间小于等于下一趟列车的出发时间,就可以继续搜索if (current.trains.empty() || current.trains.back().arrive + mintransfertime <= train.depart){//将下一趟列车添加到当前方案中current.trains.push_back(train);//更新当前方案的总票价,总耗时,换乘次数int minmoney = min({ train.soft,train.hard,train.seat });//最小的花费current.cost += minmoney;if (train.soft == minmoney)//最小花费是软卧current.soft_cnt++;else if (train.hard == minmoney)//最小花费是硬卧current.hard_cnt++;elsecurrent.seat_cnt++;//最小花费是硬座if (current.trains.size() == 1) current.time += train.arrive - train.depart;//当current大小为1,应为我们在上面先push的,这时就是第一次坐车,时间就是到达时间减去出发时间else current.time += train.arrive - current.trains[current.trains.size() - 2].arrive;//当两列车间隔满足最小换乘时间时,时间花费就是,后一辆车到达时间,减去前一辆车的到达时间if (current.trains.size() != 1) current.transfer++;//递归地搜索下一站点dfs(train.to, endp, best, current, visited);//进行回溯,恢复现场,将数量贡献恢复if (train.soft == minmoney)//最小花费是软卧current.soft_cnt--;else if (train.hard == minmoney)//最小花费是硬卧current.hard_cnt--;elsecurrent.seat_cnt--;//最小花费是硬座//回溯,将下一趟列车从当前方案中移除current.trains.pop_back();//恢复当前方案的总票价,总耗时,换乘次数minmoney = min({ train.soft,train.hard,train.seat });current.cost -= minmoney;if (current.trains.empty()) current.time -= train.arrive - train.depart;//这里我们是先pop的和上面先push的正好反过来了else current.time -= train.arrive - current.trains.back().arrive;if (current.trains.size() != 0) current.transfer--;}}//将当前站点标记为未访问visited.pop_back();
}
//定义一个函数,根据用户的输入,规划乘车方案
void plan(string start, string endp)
{//如果起点站或终点站不在站点集合中,就提示用户输入有误if (find(stations.begin(), stations.end(), start) == stations.end()){cout << "起点站不存在,请重新输入" << endl;return;}if (find(stations.begin(), stations.end(), endp) == stations.end()){cout << "终点站不存在,请重新输入" << endl;return;}if (start == endp){cout << "起点站和终点站相同,无需乘车" << endl;return;}//定义一个变量,表示最优乘车方案Plan best = { vector<Train>(),INF,INF,INF,0,0,0 };//定义一个变量,表示当前的乘车方案Plan current = { vector<Train>(),0,0,0,0,0,0 };//定义一个变量,表示已经访问过的站点vector <string> visited;//调用一个递归函数,进行深度优先搜索,寻找最优的乘车方案dfs(start, endp, best, current, visited);//如果最优的乘车方案为空,就提示用户没有找到合适的方案if (best.trains.empty()) cout << "没有找到从" << start << "到" << endp << "的合适的乘车方案" << endl;else{//否则,输出最优的乘车方案的详细信息cout << "从" << start << "到" << endp << "的最优的乘车方案如下:" << endl;printPlan(best);}
}
//定义一个函数,输入模块,获取用户的输入
void input()
{//输出欢迎信息cout << "欢迎使用春运乘车方案规划系统" << endl;//输出站点列表for (int i = 0; i < stations.size(); i++) cout << stations[i] << " ";cout << endl;//获取用户的输入string start, endp;cout << "请输入起点站:" << endl;cin >> start;cout << "请输入终点站:" << endl;cin >> endp;//调用规划函数,输出结果plan(start, endp);
}
//定义一个函数,输出模块,输出系统的相关信息
void output()
{//输出系统的名称,版本,作者等信息cout << endl;cout << "\t\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n";cout << "\t\t\t\t☆===============春运乘车方案规划系统=============☆\n";cout << "\t\t\t\t☆~~~~~~~~~~~~~~~~~~~版本:12.0~~~~~~~~~~~~~~~~~~~☆\n";cout << "\t\t\t\t☆~~~~~~~~~~~~~~~~~作者:铁路规划者~~~~~~~~~~~~~~~☆\n";cout << "\t\t\t\t☆~~~~~~~~~~~~~~~日期:2023年12月25日~~~~~~~~~~~~~☆\n";cout << "\t\t\t\t☆================================================☆\n";cout << "\t\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n";cout << "========================================================================================================================" << endl;
}
void local_file_modify(string ID, bool add, bool modify, string insert)
{fstream infile;//读文件infile.open("d:\\out.txt", ios::in);fstream f;//写文件f.open("d:\\out.txt", ios::out | ios::app);//追加写入,在原来基础上加了ios::app,并且是末尾添加if (add)//只添加{f << endl;f << insert << endl;f.close();infile.close();return;}string s;vector<string>t;while (getline(infile, s))//读入所有数据{t.push_back(s);}string file_name = "d:\\out.txt";ofstream file_writer(file_name, ios_base::out);//清空文件内容for (int i = 0; i < t.size(); i++)//刨去删除内容,或者修改的内容{int j;for (j = 0; j < t[i].size(); j++)//找到第一个空格,前面的数据就是id{if (t[i][j] == ' ')break;}if (t[i].substr(0, j) == ID)//substr判断id是否相等,相等则过滤掉continue;else//反之将其重新读入txt{f << t[i] << endl;}}if (modify)f << insert << endl;infile.close();f.close();
}
//定义一个函数,添加线路
void addTrain()
{//输出提示信息cout << "请输入要添加的线路的信息,格式为:列车编号 起点站 终点站 出发时间 到达时间 软卧票价 硬卧票价 硬座票价 " << endl;cout << "(注意 出发时间和到达时间,以分钟为单位)" << endl;// 例如:G1 北京 上海 420 1020 933 553 0// 获取用户的输入string id, from, to;int depart, arrive;int soft, hard, seat;cin >> id >> from >> to >> depart >> arrive >> soft >> hard >> seat;//创建一个新的列车对象Train train = { id,from,to,depart,arrive,soft,hard,seat };//将新的列车对象添加到时刻表中timeable.push_back(train);// 如果起点站不在站点集合中,就添加进去if (find(stations.begin(), stations.end(), from) == stations.end()){stations.push_back(from);}// 如果终点站不在站点集合中,就添加进去if (find(stations.begin(), stations.end(), to) == stations.end()){stations.push_back(to);}// 如果起点站不在邻接表中,就添加一个空的邻接表项if (adj.find(from) == adj.end()){adj[from] = vector<Train>();}// 在起点站的邻接表中添加这趟列车adj[from].push_back(train);//修改文件数据string file = id + " " + from + " " + to_string(depart) + " " + to_string(arrive) + " " + to_string(soft) + " " + to_string(hard) + " " + to_string(seat);local_file_modify(id, 1, 0, file);//只加,不删,不改// 输出添加成功的信息cout << "添加成功,已添加以下线路:" << endl;cout << id << " " << from << " " << format(depart) << " -> " << to << " " << format(arrive) << endl;
}
//定义一个函数,修改线路
void modifyTrain()
{//输出提示信息cout << "请输入要修改的线路的列车编号:" << endl;//获取用户的输入string id;cin >> id;//在时刻表中查找对应的列车对象Train* train = nullptr;for (int i = 0; i < timeable.size(); i++){if (timeable[i].id == id){train = &timeable[i];break;}}//如果没有找到,就提示用户输入有误if (train == nullptr){cout << "没有找到该列车编号,请重新输入" << endl;return;}//输出要修改的线路的原始信息cout << "要修改的线路的原始信息如下:" << endl;cout << train->id << " " << train->from << " " << format(train->depart) << " -> " << train->to << " " << format(train->arrive) << endl;//输出提示信息cout << "请输入要修改的线路的新信息,格式为:起点站 终点站 出发时间 到达时间 软卧票价 硬卧票价 硬座票价" << endl;cout << "(注意 出发时间和到达时间,以分钟为单位)" << endl;//例如:北京 上海 420 1020 933 553 0//获得用户的输入string from, to;int depart, arrive;int soft, hard, seat;cin >> from >> to >> depart >> arrive >> soft >> hard >> seat;//在起点站的邻接表中删除这趟列车//map <string,vector<Train>> adj; //表示站点之间的邻近表//adj[train->from].erase(remove(adj[train->from].begin(), adj[train->from].end(), *train), adj[train->from].end());//vector <Train> ::iterator it=adj[train->from].begin();for (auto it = adj[train->from].begin(); it != adj[train->from].end(); it++){Train t = *it;if (train->id == t.id){adj[train->from].erase(it);break;}}//修改列车对象的属性train->from = from;train->to = to;train->arrive = arrive;train->soft = soft;train->hard = hard;train->seat = seat;// 如果起点站不在站点集合中,就添加进去if (find(stations.begin(), stations.end(), from) == stations.end()){stations.push_back(from);}// 如果终点站不在站点集合中,就添加进去if (find(stations.begin(), stations.end(), to) == stations.end()){stations.push_back(to);}// 如果起点站不在邻接表中,就添加一个空的邻接表项if (adj.find(from) == adj.end()){adj[from] = vector<Train>();}// 在起点站的邻接表中添加这趟列车adj[from].push_back(*train);//修改文件string file = id + " " + train->from + " " + train->to + " " + to_string(train->depart) + " " + to_string(train->arrive) + " " + to_string(train->soft) + " " + to_string(train->hard) + " " + to_string(train->seat);local_file_modify(id, 0, 1, file);//只修改// 输出修改成功的信息//string file = id + " " + from + " " + to_string(depart) + " " + to_string(arrive) +" "+ to_string(soft) + " " + to_string(hard) + " " + to_string(seat);cout << "修改成功,已修改以下线路:" << endl;cout << train->id << " " << train->from << " " << format(train->depart) << " -> " << train->to << " " << format(train->arrive) << endl;
}
// 定义一个函数,删除线路
void deleteTrain()
{//输出提示信息cout << "请输入要删除的线路的列车编号:" << endl;//获取用户的输入string id;cin >> id;//在时刻表中查找对应的列车对象Train* train = nullptr;Train last;for (int i = 0; i < timeable.size(); i++){if (timeable[i].id == id){train = &timeable[i];last = timeable[i];break;}}//如果没有找到,就提示用户输入有误if (train == nullptr){cout << "没有找到该列车编号,请重新输入" << endl;return;}//输入要删除的线路信息cout << "要删除的线路信息如下:" << endl;cout << train->id << " " << train->from << " " << format(train->depart) << " -> " << train->to << " " << format(train->arrive) << endl;//在时刻表中删除这趟列车for (auto it = timeable.begin(); it != timeable.end(); it++){Train t = *it;if (train->id == t.id){timeable.erase(it);break;}}//在起点站的邻接表中删除这趟列车for (auto it = adj[train->from].begin(); it != adj[train->from].end(); it++){Train t = *it;if (train->id == t.id){adj[train->from].erase(it);break;}}//删除文件里的数据string file = id + " " + last.from + " " + last.to + " " + to_string(last.depart) + " " + to_string(last.arrive) + " " + to_string(last.soft) + " " + to_string(last.hard) + " " + to_string(last.seat);local_file_modify(id, 0, 0, file);//0,0代表不加,不改,只删//输出删除成功的信息cout << "删除成功,已删除以下线路:" << endl;cout << last.id << " " << last.from << " " << format(last.depart) << " -> " << last.to << " " << format(last.arrive) << endl;
}
//定义一个函数,数据操纵功能模块,实现添加、修改或者删除线路、站点信息等功能
void manipulate()
{//输出提示信息cout << "请选择要进行的操作:(输入数字)" << endl;cout << "1. 添加线路" << endl;cout << "2. 修改线路" << endl;cout << "3. 删除线路" << endl;cout << "4. 返回" << endl;//获取用户的选择string shuzi;cin >> shuzi;int choice;if (shuzi.size() != 1) choice = 6;else{if (shuzi[0] >= '1' && shuzi[0] <= '4') choice = shuzi[0] - '0';else choice = 6;}switch (choice){case 1://添加线路addTrain();break;case 2://修改线路modifyTrain();break;case 3://删除线路deleteTrain();break;case 4://返回return;default://输入错误cout << "输入有误,请重新输入" << endl;break;}cout << "--------------------------" << endl;
}//定义一个函数,查询所有线路
void queryAll()
{//输出提示信息cout << "以下是所有的线路:" << endl;//遍历时刻表,输出每一趟列车的信息for (int i = 0; i < timeable.size(); i++){Train train = timeable[i];cout << train.id << " " << train.from << " " << format(train.depart) << " -> " << train.to << " " << format(train.arrive) << endl;}
}
//定义一个函数,查询某个站点的所有线路
void queryStation()
{//输出提示信息cout << "请输入要查询的站点:" << endl;//获取用户的输入string station;cin >> station;//如果站点不在站点集合中,就提示用户输入有误if (find(stations.begin(), stations.end(), station) == stations.end()){cout << "站点不存在,请重新输入" << endl;return;}//如果站点在站点集合中,但是没有该站点为起点站的列车,即adj[station].size()==0if (adj[station].empty()){cout << "没有以该站点为起始点的列车线路" << endl;return;}//输出提示信息cout << "以下是" << station << "的所有线路" << endl;//在邻接表查找对应的站点,输出每一趟列车信息for (int i = 0; i < adj[station].size(); i++){Train train = adj[station][i];cout << train.id << " " << train.from << " " << format(train.depart) << " -> " << train.to << " " << format(train.arrive) << endl;}
}
//定义一个函数,查询某个列车的详细信息
void queryTrain()
{//输出提示信息cout << "请输入要查询的列车编号:" << endl;//获取用户的输入string id;cin >> id;//在时刻表中查找对应的列车对象Train* train = nullptr;for (int i = 0; i < timeable.size(); i++){if (timeable[i].id == id){train = &timeable[i];break;}}//如果没有找到,就提示用户输入有误if (train == nullptr){cout << "没有找到该列车编号,请重新输入" << endl;return;}//输出列车的详细信息cout << "以下是" << train->id << "的详细信息:" << endl;cout << "起点站" << train->from << endl;cout << "终点站" << train->to << endl;cout << "出发时间" << format(train->depart) << endl;cout << "到达时间" << format(train->arrive) << endl;cout << "软卧票价" << train->soft << "元" << endl;cout << "硬卧票价" << train->hard << "元" << endl;cout << "硬座票价" << train->seat << "元" << endl;
}
//定义一个函数,查询功能模块,实现查询线路的相关信息
void query()
{//输出提示信息cout << "请选择要查询的内容:(输入数字)" << endl;cout << "1.查询所有线路" << endl;cout << "2.查询某个站点的所有线路" << endl;cout << "3.查询某个列车的详细信息" << endl;cout << "4.返回" << endl;//获取用户的选择string shuzi;cin >> shuzi;int choice;if (shuzi.size() != 1) choice = 6;else{if (shuzi[0] >= '1' && shuzi[0] <= '5') choice = shuzi[0] - '0';else choice = 6;}//根据用户的选择,执行相应的操作switch (choice){case 1://查询所有线路queryAll();break;case 2://查询某个站点的所有线路queryStation();break;case 3://查询某个列车的详细信息queryTrain();break;case 4://返回return;default://输入有误cout << "输入有误,请重新输入" << endl;break;}cout << "--------------------------" << endl;
}
bool cmp(Train a, Train b)
{return a.depart < b.depart;
}
void preprocess()
{//对时刻表按照出发时间进行升序排序sort(timeable.begin(), timeable.end(), cmp);//对邻接表中的每个列表也按照也按照出发时间进行升序排序for (auto& p : adj){sort(p.second.begin(), p.second.end(), cmp);}cout << "预处理已完成" << endl;cout << "--------------------------" << endl;
}
//定义一个函数,方案规划模块,调用深度优先搜索算法,规划乘车方案
void schedule()
{//输出提示信息cout << "请选择要进行的操作:(输入数字)" << endl;cout << "1.规划乘车方案" << endl;cout << "2.返回" << endl;//获取用户的选择string shuzi;cin >> shuzi;int choice;if (shuzi.size() != 1) choice = 6;else{if (shuzi[0] >= '1' && shuzi[0] <= '2') choice = shuzi[0] - '0';else choice = 6;}//根据用户的选择,执行相应的操作switch (choice){case 1://规划乘车方案input();break;case 2://返回return;default://输入错误cout << "输入有误,请重新输入" << endl;break;}cout << "--------------------------" << endl;
}
//定义一个函数,主菜单,提供用户选择不同的功能模块
void menu(int f)
{//输出提示信息if (f)//管理员的功能模块{cout << "欢迎使用管理员系统" << endl;cout << "请选择要使用的功能模块:(输入数字)" << endl;cout << "1.数据操纵功能模块" << endl;cout << "2.查询功能模块" << endl;cout << "3.预处理模块" << endl;cout << "4.方案规划模块" << endl;cout << "5.退出" << endl;}else//用户的功能模块{cout << "欢迎使用用户游客系统" << endl;cout << "请选择要使用的功能模块:(输入数字)" << endl;cout << "1.查询功能模块" << endl;cout << "2.预处理模块" << endl;cout << "3.方案规划模块" << endl;cout << "4.退出" << endl;}//获取用户的选择string shuzi;cin >> shuzi;int choice;if (shuzi.size() != 1) choice = 6;else{if (shuzi[0] >= '1' && shuzi[0] <= '5') choice = shuzi[0] - '0';else choice = 6;if (!f) choice++;}//根据用户的选择,执行相应的操作switch (choice){case 1:{    //数据操纵功能模块if (!f)cout << "输入有误,用户无法调用此模块,请稍后登录管理员系统" << endl;elsemanipulate();break;}case 2://查询功能模块query();break;case 3://预处理mokuaipreprocess();break;case 4://方案规划模块schedule();break;case 5://退出cout << "感谢使用春运乘车方案规划系统,再见!" << endl << "--------------------------" << endl;break;default://输入有误cout << "输入有误,请重新输入" << endl << "--------------------------" << endl;break;}if (choice == 5) flag = 1;
}
//定义一个登录函数用来区分管理员与用户
void login()
{if (!tag){printf("\n");printf("\t\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");printf("\t\t\t\t☆===========欢迎使用春运乘车方案规划系统=========☆\n");printf("\t\t\t\t☆~~~~~~~~~~~~~~~~~1.管理员登陆~~~~~~~~~~~~~~~~~~~☆\n");printf("\t\t\t\t☆~~~~~~~~~~~~~~~~~2.用户登录~~~~~~~~~~~~~~~~~~~~~☆\n");printf("\t\t\t\t☆~~~~~~~~~~~~~~~~~3.退出系统~~~~~~~~~~~~~~~~~~~~~☆\n");printf("\t\t\t\t☆================================================☆\n");printf("\t\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");printf("========================================================================================================================\n");cout << "请输入您选择的登陆系统" << endl;}int op;cin >> op;if (op == 1)//选择了管理员系统,可以增加,修改,删除线路{cout << "请输入管理员密码" << endl;cout << "--------------------------" << endl;string manager_password;cin >> manager_password;while (manager_password != MANAGER_PASSWORD) {cout << "密码有误,请重新输入!!!!" << endl;cin >> manager_password;}while (true){menu(1);if (flag) break;}}else if (op == 2)//选择了用户游客登录系统,不能随意修改数据{cout << "请输入用户密码" << endl;cout << "--------------------------" << endl;string user_password;cin >> user_password;while (user_password != USER_PASSWORD) {cout << "密码有误,请重新输入!!!!" << endl;cin >> user_password;}while (true){menu(0);if (flag) break;}}else if (op == 3){cout << "谢谢您的使用,下次再见." << endl;cout << "--------------------------" << endl;flag = 5;mark = 1;}else{tag = 1;cout << "输入有误,请重新输入" << endl;cout << "--------------------------" << endl;}
}
signed main()
{//初始化全局变量init();//循环显示主菜单,直到用户选择退出while (true){login();if (flag && mark){output();//输出系统的相关信息break;}flag = 0;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/651722.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣516. 最长回文子序列

动态规划 思路&#xff1a; 字符串最长回文子序列问题可以转换为原字符串 s 和逆串 s 的最长公共子序列长度问题&#xff0c;具体推断过程可以参考 力扣1312. 让字符串成为回文串的最少插入次数问题变成了求两个字符串最长公共子序列长度问题&#xff0c;具体思路可以参考 力扣…

Win32 PE图标资源提取(ICO图标提取)

最近需要写一个提取EXE或者DLL图标资源的功能, 网上找了很久, 要么功能不好用, 最后结果如下: 1.很多是加载为HICON句柄后转换为图片保存, 全损画质..., 2.后来找了个还能用的, 详见 https://github.com/TortoiseGit/TortoiseGit/blob/master/src/Utils/IconExtractor.cpp …

cenos8.5快速部署开发环境(LAMP)

Apache 安装apache yum -y install httpd httpd-manual mod_ssl mod_perl 重启服务&#xff0c;设置自启动 systemctl start httpd systemctl enable httpd 查看apache运行状态 systemctl status httpd MySQL 下载MySQL wget http://dev.mysql.com/get/mysql57-community-re…

第十二届“中关村青联杯”全国研究生数学建模竞赛-D题:面向节能的单/多列车优化决策问题

目录 摘 要: 1 问题重述 1.1 问题背景 1.2 本文所需解决的问题 2 问题假设

前端——HTML

目录 文章目录 前言 一.HTML的基本标签 二.HTML标签 1.块级标签 1.1块级标签特征 1.2标题标签 ​编辑 1.3 水平线标签 1.4 段落标签 1.5 无序列表标签 1.6 有序列表标签 1.7 表格标签 1.8层标签 1.9 表单 2. 行级标签 2.1行级标签特征 2.2图像标签 2.3 范围…

阿里云云数据库RDS

1. 请简述阿里云云数据库RDS的主要特点和优势&#xff1f; 阿里云云数据库RDS的主要特点和优势包括高可用性、强大的扩展性、性能优化、灵活的备份与恢复功能以及专业的技术支持等。 具体来说&#xff0c;以下是阿里云RDS的一些关键优势&#xff1a; 高可用性和可靠性&#…

Leetcode刷题笔记题解(C++):1971. 寻找图中是否存在路径

思路&#xff1a; 1.建立图集&#xff0c;二维数组&#xff0c;path[0]里面存放的就是与0相连的节点集合 2.用布尔数组来记录当前节点是否被访问过&#xff0c;深度优先会使用到 3.遍历从起点开始能直接到达的点&#xff08;即与起点相邻的点&#xff09;&#xff0c;判断那…

Centos9使用chrony服务同步时间

安装chrony命令 Centos9里是预安装的&#xff0c;没有安装的话执行以下命令&#xff1a; yum install -y chronyCentos9 时间同步要使用chrony命令&#xff0c;ntp命令没有了 查看状态 #启用chronyd服务 systemctl enable chronyd#重启chronyd服务 systemctl restart chron…

操作系统(5)-----操作系统进程相关

目录 一.进程的组成 1.PCB&#xff08;进程控制块&#xff09; 2.程序段与数据段 二.进程的特征 三.进程的状态以及状态的转换 四.进程的组织 1.链接方式 2.索引方式 五.进程控制 六.进程控制相关原语 1.创建原语 2.撤销原语 3.阻塞原语 4.唤醒原语 5.切换原语 …

Elasticsearch8.11集群部署

集群就是多个node统一对外提供服务&#xff0c;避免单机故障带来的服务中断&#xff0c;保证了服务的高可用&#xff0c;也因为多台节点协同运作&#xff0c;提高了集群服务的计算能力和吞吐量。ES是一个去中心化的集群&#xff0c;操作一个节点和操作一个集群是一样的&#xf…

git删除本地分支,拉取远程分支到本地新分支

删除本地Git分支的过程相对简单。以下是在命令行中执行此操作的步骤&#xff1a; 切换到一个不同的分支&#xff1a; 在删除一个分支之前&#xff0c;你需要确保自己不在那个分支上。通常&#xff0c;你可以切换到主分支或其他任何分支。例如&#xff0c;要切换到主分支&#x…

【Linux】-同步互斥的另一种办法-信号量

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

JVM系列——基础知识

Java运行区域 程序计数器&#xff08;Program Counter Register&#xff09; 程序计数器是一块较小的内存空间&#xff0c;它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里[1]&#xff0c;字节码解释器工作时就是通过改变这个计数器的值来选取下一…

PCIE 4.0 Equalizaiton(LTSSM 均衡流程)

1. 均衡 在Tx端有FFE&#xff08;Feed Forward Equalizer&#xff0c;前馈均衡器&#xff09;&#xff1b;在Rx端有&#xff1a;CTLE&#xff08;Continuous Time Linear Equalizer&#xff0c;连续时间线性均衡器&#xff09;和DFE&#xff08;Decision Feedback Equalizer&a…

HarmonyOS 鸿蒙应用开发 (七、HTTP网络组件 axios 介绍及封装使用)

在HarmonyOS应用开发中&#xff0c;通过HTTP访问网络&#xff0c;可以使用官方提供的ohos.net.http模块。但是官方提供的直接使用不太好使用&#xff0c;需要封装下才好。推荐使用前端开发中流行的axios网络客户端库&#xff0c;如果是前端开发者&#xff0c;用 axios也会更加顺…

Conan2: starting at a text book example

“From using libraries already packaged by Conan, to how to package your libraries and store them in a remote server alongside all the precompiled binaries.” Clone the sources of this example project from github, and open the simple_cmake_project directo…

MySQL 运算符BETWEEN.NOT. BETWEEN.IN.NOT IN

MySQL 运算符 本章节我们主要介绍 MySQL 的运算符及运算符的优先级。 MySQL 主要有以下几种运算符&#xff1a; 算术运算符 MySQL 支持的算术运算符包括: 运算符作用加法–减法*乘法/ 或 DIV除法% 或 MOD取余 在除法运算和模运算中&#xff0c;如果除数为0&#xff0c;将是…

MySQL封装JDBC为工具类(JDBC简化)

1&#xff1a;在我们对一个表的增删改查中我们可以发现&#xff0c;如果一个表要进行增删改查四个操作时&#xff0c;我们可能要四个方法&#xff0c;四个方法中每一个方法都需要进行JDBC的连接&#xff0c;如果每一步都按照JdbcTemplate方式写的话可能会简化一点&#xff0c;但…

【GitHub项目推荐--推荐一个开源的任务管理工具(仿X书/X钉)】【转载】

推荐一个开源的任务管理工具&#xff0c;该工具会提供各类文档协作功能、在线思维导图、在线流程图、项目管理、任务分发、即时 IM&#xff0c;文件管理等等。该开源项目使用到 Vue、Element-UI、ECharts 等技术栈。 开源地址&#xff1a;www.github.com/kuaifan/dootask 预览地…

Ribbon 体系架构解析

前面已经介绍了服务治理相关组件&#xff0c;接下来趁热打铁&#xff0c;快速通关Ribbon&#xff01;前面我们了解了负载均衡的含义&#xff0c;以及客户端和服务端负载均衡模型&#xff0c;接下来我们就来看下SpringCloud 下的客户端负载均衡组件Ribbon 的特点以及工作模型。 …