这篇文章很详细,也很多希望可以好好看看!看完C 稳过!
一、12306应该具备那些功能 1.查询(一个月以内的): 1.查车票:出发地 目的地 出发时间->显示经过两站车票信息 (余票,车次信息可直接查询直接打印,是否为过路车,历时不是总历时,是两站间历时)(只有这种查询方式能查询余票) 2.车站车次查询: 车站 出发时间段 到达时间段->打印始发站与终点站信息(车站与时间)。 (查询的的车站即作为始发站,又作为终点站) 3.车次查询:车次 出发日期->打印该车次详细信息 (经过站点序号,站名,到时,发时,停留,终点站,起始站,历时) 2.操作 1.购票(某个区间的票-1)一天限购五张,一个月以内的。 2.退票 (某个区间的票 1) 火车开了之后,不能退票,只能改签。 3.改签(相当于退票 从新购票)一张票仅能改签一次 4.刷新 相当于重新读入 5.换乘 两个城市不能接联通,需要借助最短,需要找出中转城市,可能一个在佳木斯,一个在宜宾,这不一定是换乘一次,只要有火车站无非是换乘的次数多一点,反正能到(间隔大于10min)。 3.管理员操作 1.增删查改站点(查)可以继承一个查询类 票一旦起售,不可修改站点,虽然没怎么见过火车站被拆得,但是还是有,但是拆除不可能是突然的拆除,所以会提前收到消息,先停售,再删除,修改名称可以直接修改。站点到站时间只能修改一个月以后的。 2.放票 无特殊需要,无需操作,每天的列车表都是一样的。 3.增加车次 (没有特殊要求,国家铁路局规定站点名唯一,车次名唯一) 4.用户端操作 1.各种查询 2.买退改,重点是换乘(这个不一定好写) 2.查询已买到的票 二、根据数据写出大体思路
- 时间类:
- 数据: a) 应包含年月日时分
- 函数: a) 买票时间为系统时间,应该写一个自动获取函数。 b) 应该写一个打印时间函数 c) 按时间查询的时候需要获取时间,需要些get函数 d) 为了便于管理员修改信息,需要设置set函数 e) 方便输入输出重载输入输出 f) 需要按照时间排序,可能需要重载小于号。 g) 因为提前30天放票,所以这里要考虑写判断闰年的函数,和加减日期的函数(还有分钟的单独写,用于停靠时间,没见过一个车停靠超过一个小时的)
- 站点数据类
- 数据 a) 站点名称 (本来想写一个id来着,但是中国的火车站名字唯一,自己就可以当作编号) b) 经过车次(int 型vector的下标)写成vector比较合适
- 函数 a) 打印车次信息,理论上实可以返回一个Vector容器,这样就可以得到车次序号,因为在数据类中看不到列车数据。如果不行可以以引用的形式传入一个vector进行复制。 b) 重载输入输出 c) Set函数 修改数据 d) Insert 函数 增添 e) Delete 函数 删除
- 列车站台数据类 1) 数据 a) 出发时间 b) 到站时间 c) 出发时段 1-4 d) 到达时段1-4 e) 站台伪指针(int 下标实现) 2) 函数 Get set函数 加重载输入输出全家桶
- 列车类包含
- 数据 a) 车次(唯一) b) 停靠站 到达每一个站的时间(多个列车经过相同的车站,但是时间不一定一样)。停靠站可以写一个Vector但是vector写一个pair类型pair(string,pair(int,时间)),因为站名唯一,所以可以将站名用map映射. 写成一个列车站台数据类,这里用vector 存即可。 c) 该车次某个站的余票 每个车次的每张票都是独立的这里应该写到列车类。 d) 每张票卖给了谁,用户的信息(存vector,vector的下标1,存某个身份证,代表第一张票,关于什么靠窗,站票卧铺,每节车厢都一样,不用考虑,需要考虑吧基于某种函数关系即可算出在什么位置)。
- 函数 a) 买票(判断是否大于五张) b) 退票( 合起来就是改签 ) c) 查询余票,给定区间。 d) 刷新 e) 获得用户信息,方法跟上一条站点信息一样。 f) 打印停靠站以及信息 g) 重载输入输出 h) 增查改站点(这个不需要条件,可以直接操作修改站名,同时修改,还有站点信息) i) 删站点,改时间这些需要调整一个月以后的。 关于用Vector存火车站点的问题要调整一下。String一般按24字节每辆火车按平均20个站点计算,中国客运火车6000 (某度不知地道准不准),就会有2.7MB的火车数据文件读取,刷新一次读取这么多。而中国一共就有5000 的火车站,四舍五入算他1万,用一个usigned short 存6万,肯定够用,这样读取数据会快一点,所以string 非常好也不能滥用。
- 车票类:
- 数据: a) 车票编号:基于的hash算法(这里保证每一张票的编号不一样即可) b) 购票日期: c) 车次信息: d) 出发站: e) 目标站: f) 乘车时间: 只存一个月的(到时候按时间排序,超过乘车时间一个月,存成日志文件) g) 购票人信息:int 指针;
- 函数 a) 打印车票 b) Get所有的信息多个函数; c) 不设置set函数,改签,跟退票之后hash值不同,直接销毁即可。 d) 重载输入输出 e) 无参初始化 f) 含参初始化
- 用户数据类: 数据 姓名 身份证号码 已买到的票: 手机号码: 函数 a) 重载输入输出 b) Get set函数(仅限于手机号的修改,get是全部) c) 无参初始化 d) 含参初始化 中规中矩没有特殊操作
- 查询基类: a) 车站数据 b) 列车数据 c) 用户数据 d) 车票数据(也是记录) 函数 a) 查车票:出发地 目的地 出发时间->显示经过两站车票信息余票,车次信息,目的地,出发地模糊查询,一个市的站都会出来。 能到达的车就是出发站与目的站的列车表中重合的部分 补充:如果不能直接到达,还需要考虑换乘,换乘实现实现的话,一开始没思路,用BFS的思想,用一个queue将初始站的所有车次的所有站点放到queue里,找出第一个车放到queue里,找到到目的地的车就储存,当第一层既出发站的所有经过地点都没有可换乘车辆时,才进行二次检索,只能换乘一次。 b) 车站车次查询: 车站 出发时间段 到达时间段->打印始发站与终点站信息(车站与时间)。 (查询的的车站即作为始发站,又作为终点站) 出发时段有四个0-6 6-12 12-18 18-24 编号1-4,0-24就不做限定 实现直接在车站信息中调取车次数据的下标,判断即可,可以find_if()。 c) 车次查询 打印车次详细信息,直接车站数据,find()即可。 8.用户端: 继承查询基类, 登陆: 查询自己的信息: 购票: 先查询,找到合适的车,输入传入起始站,目标站,车次,利用之前的 函数,配合可以完成操作。 退票: 从已买到的票中把票退了,数据类中以之前写了相关的函数 改签:先退后买。 换乘://把他写到了查询类里了
- 管理端:
- 增删查改站点(查)可以继承一个查询类 票一旦起售,不可修改站点,虽然没怎么见过火车站被拆得,但是还是有,但是拆除不可能是突然的拆除,所以会提前收到消息,先停售,再删除,修改名称可以直接修改。站点到站时间只能修改一个月以后的。 2.放票 无特殊需要,无需操作,每天的列车表都是一样的。 3.增加车次 (没有特殊要求,国家铁路局规定站点名唯一,车次名唯一) 能够查询所有的用户信息(按姓名,身份证号)。 4.户信息,不对用户信息进行修改。 5 Map 按车次 查记录
- Map 按身份证 查记录
- Map 按姓名(一名多人)查记录
- 按车站 查记录 12306管理端能查到好几年之前的,这就得需要动态读取,文件,和动态生成文件名,目前还没有找到实现的方法,如果不行,就分成这个月,和这个月之前的。
#include<bits/stdc .h.>
using namespace std;
class Time
{
int year,month,day;
int hour,mini;
public:
Time(){loadtime();}
Time(int y,int m,int d):year(y),month(m),day(d){}; //用于车票生成。
void loadtime(); //定义时间获取函数,用于获取买票时间,直接从系统读入;
friend istream & operator>>(istream &in,Time & a);
friend stringstream & operator>>(stringstream &in,Time & a);
friend ostream & operator<<(ostream &out,Time & a); //排序函数,用于车票信息的储存;
bool operator <(const Time &d)const; //重载小于号,用于数据时间排序,不需要修改数据const
int judge() const; //判断是否为闰年;
int judge(int year) const ;//写一个有参的判断函数;
Time operator (int a) ; //重载加号,用于放票;
bool operator ==(Time & a) ; //判断是否为一天;
friend int operator -(Time a,Time b); //计算两段时间间隔;
void print()const;//打印时间;
bool operator>(Time&a);
int getday(){return day;}
int getmonth(){return month;}
int getyear(){return year;}
int gethour(){return hour;}
void set();
void setmonth(int a){month=a;}
pair<int,int> tksj(Time&b); //停靠时间
void seth(int a,int b){hour=a;mini=b;}
};
bool Time ::operator>(Time&a)
{
return (year!=a.year)?year>a.year:month!=a.month?month>a.month:day!=a.day?day>a.day:0;
}
bool Time::operator ==(Time & a)
{
return (year!=a.year)?0:month!=a.month?0:day!=a.day?0:hour!=a.hour?0:mini==a.mini;
}
Time Time::operator (int a)
{
int m[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
day =a;
int flag=1;
while(day>m[month]){
if(month==2){
if(day>m[month] judge()){
day-=m[month] judge();
month ;
}
}
else {
day=day-m[month];
month ;
}
if(month>12){
month-=12;
year ;
}
}
}
int operator -(Time a,Time b)
{
int monthdays[2][12] = { { 31,28,31,30,31,30,31,31,30,31,30,31 },{ 31,29,31,30,31,30,31,31,30,31,30,31 } };
int yeardays[2] = { 365,366 };
int sumdays=0;
if (a.year == b.year&& a.month == b.month){
sumdays = b.day - a.day;
}
else
if (a.year == b.year){
sumdays = monthdays[a.judge(a.year)][a.month-1] - a.day;
for (int i = a.month; i < b.month-1; i )
sumdays = monthdays[a.judge(a.year)][i];
sumdays = b.day;
}
else{
sumdays = monthdays[a.judge(a.year)][a.month-1] - a.day;
for (int i = a.month; i < 12; i )
sumdays = monthdays[a.judge(a.year)][i];
for (int i = a.year 1; i < b.year; i )
sumdays = yeardays[a.judge(i)];
for (int i = 0; i < b.month - 1; i )
sumdays = monthdays[a.judge(b.year)][i];
sumdays = b.day;
}
return sumdays;
}
int Time::judge() const{
if(year % 4 == 0 && year 0 != 0 ||year % 400 == 0) return 1;
else return 0;
}
int Time::judge(int year) const{
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)return 1;
else return 0;
}
void Time::loadtime(){
time_t rawtime;
struct tm *ptminfo;
time(&rawtime);
ptminfo = localtime(&rawtime);
year=ptminfo->tm_year 1900;
month=ptminfo->tm_mon 1;
day=ptminfo->tm_mday;
hour=ptminfo->tm_hour;
mini=ptminfo->tm_min;
}
istream & operator>>(istream &in,Time & a){
in>>a.year>>a.month>>a.day>>a.hour>>a.mini;
return in;
}
ostream & operator<<(ostream &out,Time & a)
{
out<<a.year<<" "<<a.month<<" "<<a.day<<" "<<a.hour<<" "<<a.mini<<' ';
return out;
}
stringstream & operator>>(stringstream &in,Time & a){
in>>a.year>>a.month>>a.day>>a.hour>>a.mini;
return in;
}
bool Time:: operator <(const Time &d)const{
return year!=d.year?year<d.year:month!=d.month?month<d.month:day!=d.day?hour<d.hour:mini<d.mini;
}
void Time:: print()const
{
cout<<year<<"年"<<month<<"月"<<day<<"日";
printf("d:dn",hour,mini);
}
void Time::set()//容错处理
{
int monthdays[2][12] = { { 31,28,31,30,31,30,31,31,30,31,30,31 },{ 31,29,31,30,31,30,31,31,30,31,30,31 } };
cout<<"请依次输入"<<" 年"<<" 月"<<" 日"<<" 小时"<<" 分钟"<<endl;
cin>>year;
while(year<2019){cout<<"不是正确时间,请重新输入年"<<endl;cin>>year;}
cin >>month;
while(month>12||month<1){cout<<"不是正确时间,请重新输入月"<<endl;cin>>month;}
cin>>day;
while(monthdays[judge()][month-1]<day||day<1){cout<<"不是正确时间,请重新输入日"<<endl;cin>>day;}
cin>>hour;
while(hour>24||hour<0){cout<<"不是正确时间,请重新输入小时"<<endl;cin>>hour;}
cin>>mini;
while(mini>60||mini<0){cout<<"不是正确时间,请重新输入分钟"<<endl;cin>>mini;}
cout<<"时间已更改为"<<endl;
print();
}
pair<int,int> Time::tksj(Time &b)//高铁晚上不开车,不考虑超过一天;
{
pair<int,int> w;
if(mini<b.mini)
{
w.second=mini-b.mini 60;
w.first=hour-b.hour-1;
return w;
}
w.second=mini-b.mini;
w.first=hour-b.hour;
return w;
}
/*
int main()
{
Time demo;
demo.loadtime();
cout<<demo<<endl;
demo.print();
}*/
/*int main()
{
Time demo1;
cin>>demo1;
Time demo2(demo1);
demo1.print();
}*/
/*
int main()
{
Time demo;
cout<<demo.judge()<<endl;
cout<<demo.judge(2008)<<endl;
}*/
/*
int main()
{
set<Time>demo;
Time tx;
int n=3;
while(n--)
{
tx.set();
demo.insert(tx);
}
set<Time>::iterator po;
for(po=demo.begin();po!=demo.end();po ) (*po).print();
}*/
/*
int main()
{
Time demo1,demo2;
demo1.loadtime();
cin>>demo2;
cout<<demo2.tksj(demo1).first<<' '<<demo2.tksj(demo1).second;
}*/
struct piao
{
string name;
int sum[31];
bool operator <(const piao& a)const
{
return name<a.name;
}
};
class Station
{
string name; //车站名唯一
int crotrain;//经过车次数量
vector<piao> checi; //第一个string是车次,第二个是余票
//这个车站最多买多少张票,不一定跟总票数相同
public:
Station(string na,int n);
Station():name(""),crotrain(0){checi.clear();}
void print(int riqi);
void insert(string a);//为站台增加车次
vector<piao>& quecheci();
friend istream& operator>>(istream &in,Station & a);
friend ostream& operator<<(ostream &out,Station & a);
bool del(string a);
bool set(string a,int b,int c);// 如果需要调度余票,可以修改
void setname(string a){this->name=a;}
string getname(){return name;}
void buytic(string a,int b);
void rebac(string a,int b);
};
void Station::rebac(string a,int b)
{
for(auto po=checi.begin();po!=checi.end();po )
if(po->name==a) po->sum[b] ;
}
void Station::buytic(string a,int b)
{
for(auto po=checi.begin();po!=checi.end();po )
if(po->name==a) po->sum[b]--;
}
Station::Station(string na,int n)
{
name=na;
crotrain=n;
for(int i=0;i<n;i )
{
cout<<"输入车次 余票:n";
piao w;
cin>>w.name;
for(int i=0;i<31;i ) cin>>w.sum[i];
checi.push_back(w);
}
}
istream& operator>>(istream& in,Station & w)
{
in>>w.name>>w.crotrain;
//cout<<w.crotrain<<endl;
for(int i=0;i<w.crotrain;i )
{
piao qq;
in>>qq.name;
for(int i=0;i<31;i ) in>>qq.sum[i];
w.checi.push_back(qq);
}
return in;
}
ostream& operator<<(ostream& out,Station & w)
{
out<<w.name<<" "<<w.crotrain<<endl;
for(auto po=w.checi.begin();po!=w.checi.end();po )
{
out<<po->name<<endl;
for(int i=0;i<31;i ) out<<po->sum[i]<<' ';
out<<endl;
}
return out;
}
void Station::print(int b)
{
cout<<name<<":"<<endl;
for(auto po=checi.begin();po!=checi.end();po )
{
cout<<"车次:"<<po->name<<" 余票:"<<po->sum[b]<<endl;
}
}
vector<piao>& Station ::quecheci()
{
return checi;
}
void Station::insert(string a)
{
piao w;
w.name=a;
for(int i=0;i<31;i ) cin>>w.sum[i];
checi.push_back(w);
}
bool Station::del(string a)
{
for(auto po=checi.begin();po!=checi.end();po )
{
if(po->name==a) {checi.erase(po);break;}
}
if(checi.size()!=crotrain)
{
crotrain=checi.size();
return 1;
}
else return 0;
}
bool Station::set(string a,int b,int c)
{
for(auto po=checi.begin();po!=checi.end();po )
{
if(po->name==a) {
po->sum[c]=b;
return 1;
}
else return 0;
}
}
/*
int main()
{
int n;
string a;
cin>>n>>a;
Station demo(a,n) ;
demo.print();
}
*/
/*
int main()
{
Station demo;
cin>>demo;
cout<<demo;
}*/
/*
int main()
{
Station demo;
int a;
string b;
cin>>b>>a;
demo.insert(b,a);
cin>>b>>a;
demo.insert(b,a);
vector<pair<string,int>>w=demo.quecheci();
for(auto po=w.begin();po!=w.end();po )
cout<<po->first<<' '<<po->second<<endl;
}*/
/*
int main()
{
Station demo;
string a;
cin>>a;
demo.setname(a);
int b;
cin>>a>>b;
demo.insert(a,b);
cin>>a>>b;
demo.insert(a,b);
demo.print();
cin>>a;
cout<<demo.del(a)<<endl;
cin>>a;
cout<<demo.del(a);
cin>>a>>b;
cout<<demo.set(a,b)<<endl;
cin>>a>>b;
cout<<demo.set(a,b)<<endl;
demo.print();
}*/
//修改后从新测试,get/set比较比较简单,一般不会写错。
/*
int main()
{
Station demo;
string b;
cin>>b;
demo.insert(b);
cin>>b;
demo.insert(b);
vector<piao>w=demo.quecheci();
for(auto po=w.begin();po!=w.end();po )
{
cout<<po->name<<' ';
for(int i=0;i<31;i ) cout<<po->sum[i]<<' ';
cout<<endl;
}
}*/
class Zt //中规中矩的全家桶数据类
{
pair<int,int> arrive; //在某站的出发到达时家间;
pair<int,int> leave;
string station; //作为数据类时指向vector站台;
int piao[31];// 实际上存在多少票,今天五号,五号前的是下个月,五号后是这个月,不能买今天前的票。
public:
Zt(string a,int c,int d,int e,int f):station(a){setarrive(c,d);setleave(e,f);fill(piao,piao 31,100);}
Zt(){fill(piao,piao 31,100);}
pair<int,int> &getarrive(){return arrive;}
pair<int,int> &getleave(){return leave;}
int getarr(); //出发时段到达只是时段
int getlea();
string getsta()const{return station;}
void setarrive(int a,int b){arrive.first=a;arrive.second=b;} //用于修改出站到站时间;
void setleave(int a,int b){leave.first=a;leave.second=b;}
void setsta(string a){station=a;}
void printtk();
void print();
void printa();
void printl();
int getpiao(int i){return piao[i];}
void setpiao(int a,int b){piao[b]=a;}
friend istream&operator>>(istream &in,Zt& a);
friend ostream&operator<<(ostream &out,Zt& a);
};
void Zt:: print()
{
cout<<station<<endl;
printf("d:d ",arrive.first,arrive.second);
//cout<<arrive.first<<arrive.second<<endl;
printf("d:dn",leave.first,leave.second);
// cout<<leave.first<<leave.second<<endl;
}
void Zt:: printl()
{
cout<<station<<endl;
printf("d:dn",leave.first,leave.second);
}
void Zt:: printa()
{
cout<<station<<endl;
printf("d:d ",arrive.first,arrive.second);
}
int Zt::getarr()
{
if(arrive.first>=0||arrive.first<6) return 1;
else if(arrive.first>=6||arrive.first<12) return 2;
else if(arrive.first>=12||arrive.first<18) return 3;
else return 4;
}
int Zt::getlea()
{
if(leave.first>=0||leave.first<6) return 1;
else if(leave.first>=6||leave.first<12) return 2;
else if(leave.first>=12||leave.first<18) return 3;
else return 4;
}
void Zt::printtk()
{
cout<<leave.second-arrive.second<<"分钟 "<<endl;//没有超过一个小时的;
}
istream&operator>>(istream &in,Zt& a)
{
in>>a.station;
// cout<<a.station;
in>>a.arrive.first;
// cout<<a.station;
in>>a.arrive.second;
// cout<<a.station;
in>>a.leave.first;
// cout<<a.station;
in>>a.leave.second;
//cout<<a.station;
for(int i=0;i<31;i ) in>>a.piao[i];
return in;
}
ostream&operator<<(ostream &out,Zt &a)
{
out<<a.station<<' '<<a.arrive.first<<' '<<a.arrive.second<<' '<<a.leave.first<<' '<<a.leave.second<<' ';
for(int i=0;i<31;i ) out<<a.piao[i]<<' ';
out<<endl;
return out;
}
/*
int main()
{
string a;
int b,c,d,e;
Zt demo(a,b,c,d,e);
cout<<demo.getpiao(15)<<endl;
}*/
/*
int main()
{
Zt demo1;
vector<Zt>demo;
while(cin>>demo1) demo.push_back(demo1);
cout<<demo1;
}*/
/*
int main()
{
short n;
cin>>n;
Zt demo(n);
demo.print();
demo.printtk();
cout<<demo.getlea()<<endl;
cout<<demo.getarr()<<endl;
cout<<demo.getsta()<<endl;
}
*/
/*
int main()
{
Zt demo;
demo.setarrive();
demo.setleave();
cout<<demo.getarrive()<<endl;
cout<<demo.getleave()<<endl;
}
*/
/*
int main()
{
Zt demo;
int n;
cin>>n;
demo.setpiao(n);
cout<< demo.getpiao();
}*/
class Train
{
string train; //车次
vector<Zt> station;
vector<string>people;//谁买了票指向peo下标,居题买那张票,再等用户的数据,或者存身份证。
//双重map,不如直接string
map<string,int> ys;
struct node
{
int val;
int len;
int lazy;
int l,r;
}tree[31][300005];
public:
Train():train(""){people.clear();station.clear();}
Train(string tr):train (tr){people.clear();station.clear();}
pair<int,int> buytic(string a,string b,int riqi);
void reback(string a,string b,int riqi);
void insert(string a,int d,int f,int g,int h,string w);
bool del(string a);
void cx(string a); //查到就打印,查不到就拉倒
void setarrive(string a);//修改某个站的到站时间出发时间
void setleave(string a);
void setsta(string a);
int cxyp(string a, string b,int c);
vector<string>&getpeople(){return people;}
// void printf();无法获取站台信息,只能传引用了
vector<Zt>& getzt(){return station;}
friend istream&operator>>(istream& in,Train &a);
friend ostream&operator<<(ostream& out,Train &a);
void settr(string a){train=a;}
string gettr(){return train;}
//void built_tree( int node, int left, int right,int day );
// void pushdown(int root,int day) ;//向下传递lazy标记
// int query(int root,int l,int r,int day); //计算区间和
// void update(int root,int l,int r,int addval,int day); //区间更新
};
/*void Train:: built_tree(int root,int l,int r,int day) //建树
{
int mid;
tree[day][root].lazy=0;
tree[day][root].l=l;
tree[day][root].r=r;
tree[day][root].len=r-l 1;
if (l==r) tree[day][root].val=station[l].getpiao(day);
else
{
mid=(l r)/2;
built_tree(root*2,l,mid,day);
built_tree(root*2 1,mid 1,r,day);
tree[day][root].val=min(tree[day][root*2].val,tree[day][root*2 1].val);
}
}*/
/*void Train:: pushdown(int root,int day) //向下传递lazy标记
{
if (tree[day][root].lazy)
{
tree[day][root*2].lazy =tree[day][root].lazy;
tree[day][root*2 1].lazy =tree[day][root].lazy;
tree[day][root*2].val =tree[day][root].lazy;
tree[day][root*2 1].val =tree[day][root].lazy;
tree[day][root].lazy=0;
}
}
int Train:: query(int root,int l,int r,int day) //计算区间和
{
int mid;
if (tree[day][root].l>=l&&tree[day][root].r<=r)
return tree[day][root].val;
if (tree[day][root].l>r||tree[day][root].r<l)
return 0x7f7f7f7f;
if (tree[day][root].lazy) pushdown(root,day);
return min(query(root*2,l,r,day),query(root*2 1,l,r,day));
}
void Train:: update(int root,int l,int r,int addval,int day) //区间更新
{
int mid;
if (tree[day][root].l>=l&&tree[day][root].r<=r)
{
tree[day][root].lazy =addval;
tree[day][root].val =addval;
return;
}
if (tree[day][root].l>r||tree[day][root].r<l)
return;
if (tree[day][root].lazy) pushdown(root,day);
update(root*2,l,r,addval,day);
update(root*2 1,l,r,addval,day);
tree[day][root].val=min(tree[day][root*2].val,tree[day][root*2 1].val);
}*/
pair<int,int> Train::buytic(string a,string b,int c) //站台的票和列车票是分步的 ,这是买票操作的一部分。
{
pair<int,int> www;
// update(1,ys[a],ys[b],-1,c);
www=station[ys[a]].getleave();
return www;
}
void Train::reback(string a,string b,int riqi)
{
//update(1,ys[a],ys[b],1,riqi);
}
void Train::insert(string a,int d,int f,int g,int h,string w)
{
Zt tem(a,d,f,g,h);
if(w=="END"||w=="end"||w=="End")
{
station.push_back(tem);
ys.insert(make_pair(a,station.size()-1));
}
else {
station.insert(station.begin() ys[w],tem);
for(auto po=station.begin() ys[w]-1;po!=station.end();po )
{
ys.insert(make_pair(po->getsta(),po-station.begin()));
}
}
// for(int i=0;i<=31;i )built_tree(0,0,station.size()-1,i);
}
int Train::cxyp(string a,string b,int c)
{
// return query(1,ys[a],ys[b],c);
}
/*
void Train::print()
{
for(auto po=station.begin();po!=station.end();po )
{
cout<<
}
}*/
bool Train::del(string a)
{
bool flag=0;
for(auto po=station.begin();po!=station.end();po )
{
if(po->getsta()==a)
{
station.erase(po);
flag=1;
break;
}
}
return flag;
}
void Train::cx(string a)
{
for(auto po=station.begin();po!=station.end();po )
{
if(po->getsta()==a)
{
po->print();
po->printtk();
break;
}
}
}
void Train::setarrive(string a)
{
for(auto po=station.begin();po!=station.end();po )
{
if(po->getsta()==a)
{
int a,b;
cin>>a>>b;
po->setarrive(a,b);
break;
}
}
}
void Train:: setleave(string a)
{
for(auto po=station.begin();po!=station.end();po )
{
if(po->getsta()==a)
{
int a,b;
cin>>a>>b;
po->setleave(a,b);
break;
}
}
}
void Train::setsta(string a)
{
for(auto po=station.begin();po!=station.end();po )
{
if(po->getsta()==a)
{
po->setsta(a);
break;
}
}
}
istream&operator>>(istream& in,Train &a)
{
//vector<Zt> ww;
a.ys.clear();
int m,n;
Zt demo;
in>>a.train>>n>>m;//=0;
while(n--)
{
in>>demo;
a.station.push_back(demo);
a.ys.insert(make_pair(demo.getsta(),a.station.size()-1));
// cout<<ww.station.size()<<endl;
}
// a.station.swap(ww);
while(m--)
{
string w;
in>>w;
a. people .push_back(w);
}
// for(int i=0;i<=31;i )a.built_tree(0,0,a.station.size()-1,i);
return in;
}
ostream&operator<<(ostream& out,Train &a)
{
out<<a.train<<' '<<a.station.size()<<' '<<a.people.size()<<endl;
for(auto po=a.station.begin();po!=a.station.end();po ) out<<*po<<' ';
for(auto po=a.people.begin();po!=a.people.end();po ) out<<*po<<' ';
out<<endl;
return out;
}
/*
int main()
{
Train demo;
cin>>demo;
cout<<demo;
}*/
/*
int main()
{
Train demo;
short a,b;
int c;
cin>>a>>c;
demo.insert(a,c);
cin>>b>>c;
demo.insert(b,c);
cout<<demo.cxyp(a,b)<<endl;
demo.buytic(a,b);
cout<<demo.cxyp(a,b)<<endl;
demo.reback(a,b);
cout<<demo.cxyp(a,b)<<endl;
}
*/
/*
int main()
{
Train demo;
cin>>demo;
short int a;
cin>>a;
demo.cx(a);
demo.del(a);
demo.cx(a);
cin>>a;
demo.setarrive(a);
demo.cx(a);
demo.setleave(a);
demo.cx(a);
demo.setsta(a);
demo.cx(a);
}*/
/*
int main()
{
Train demo;
cin>>demo;
cout<<demo.gettr()<<endl;
string tem;
cin>>tem;
demo.settr(tem);
cout<<demo.gettr()<<endl;
}*/
int main()
{
Train demo;
cin>>demo;
string a,b;
int c;
int d,e,f,g;
cin>>a>>d>>e>>f>>g>>b;
demo.insert(a,d,e,f,g,b);
cin>>a>>b>>c;
cout<<demo.cxyp(a,b,c)<<endl;
cin>>a>>b>>c;
cout<<demo.cxyp(a,b,c)<<endl;
demo.buytic(a,b,c);
cout<<demo.cxyp(a,b,c)<<endl;
demo.reback(a,b,c);
cout<<demo.cxyp(a,b,c)<<endl;
}
class Tick //即使车票,又是记录
{
Time buy;
Time leave; //出发时间,用于确定存日志文件
string from;
string to;
string id;
string name;
public:
//只有get函数
Tick():from(" "),to(" "),id(" "){}
Tick(Time b,Time l,string f,string t,string i,string w):buy(b),leave(l),from(f),to(t),id(i),name(w){}
Time&getbuy(){return buy;}
Time&getlea(){return leave;}
string getfrom(){return from;}
string getto(){return to;}
string getid(){return id;}
string getname();//本来想hash,但是有点复杂
void print();
string getna(){return name;}
bool operator ==(Tick &a);
friend istream& operator>>(istream& in,Tick &a );
friend ostream& operator<<(ostream &out,Tick &a );
};
string Tick::getname()
{
string w;
stringstream tem;
w.clear();
tem.clear();
tem<<leave.getday();
tem<<leave.getmonth();
tem<<leave.getyear();
tem>>w;
w=w id from to;
return w;
}
bool Tick::operator ==(Tick &a)
{
return a.buy==buy?(a.leave==leave?(from==a.from?(to==a.to?id==a.id:0):0):0):0;
}
istream& operator>>(istream &in,Tick &a )
{
in>>a.buy>>a.leave>>a.from>>a.to>>a.id>>a.name;
return in;
}
ostream& operator<<(ostream &out,Tick &a )
{
out<<a.buy<<' '<<a.leave<<' '<<a.from<<' '<<a.to<<' '<<a.id<<' '<<a.name<<endl;
return out;
}
void Tick::print()
{
cout<<leave<<endl;
cout<<from<<"----->"<<to<<endl;
cout<<id<<endl;
}/*
int main()
{
Tick demo;
cin>>demo;
cout<<demo.getname()<<endl;
}*/
/*
int main()
{
Tick demo;
cin>>demo;
cout<<demo;
}
*/
/*
int main()
{
Time demo1,demo2;
short a,b;
string id;
cin>>demo1>>demo2>>a>>b>>id;
Tick demo(demo1,demo2,a,b,id);
cout<<demo.getbuy()<<endl;
cout<<demo.getlea()<<endl;
cout<<demo.getfrom()<<endl;
cout<<demo.getto()<<endl;
cout<<demo.getid()<<endl;
}*/
/*
int main()
{
string a,b,c;
cin>>a>>b>>c;
Time q, e;
cin>>q>>e;
Tick demo(q,e,a,b,c);
cout<<demo;
demo.print();
}*/
/*
int main()
{
Tick demo;
cin>>demo;
demo.print();
}*/
class User//用户信息
{
string name;
string id; //不能改
vector<string > tic;
string phone;
string key;
bool ban;//黑名单
public:
User():name(""),id(""),phone(""){tic.clear();}
User(string a,string b,string c):name(a),id(b),phone(c){tic.clear();}
void buytic(string a){ tic.push_back(a);} //只考虑买就行了,判断能不能买在下面的类.
void setph(string p){ phone=p;}
vector<string >& gettic(){return tic;}
string getname(){return name;}
string getphone(){return phone;}
string getid(){return id;}
string getkey(){return key;}
void del(string a); //这是系统操作出行后,就看不到订单了。
int getboupiao(){return tic.size();}
bool getban(){return ban;}
friend istream&operator>>(istream&in,User&a);
friend ostream&operator<<(ostream&out,User&a);
};
void User::del(string a)
{
for(auto po=tic.begin();po!=tic.end();po )
{
if(*po==a) tic.erase(po);
}
}
istream&operator>>(istream&in,User&a)
{
int w;
in>>a.name>>a.id>>a.phone>>a.key>>a.ban>>w;
while(w--) //一个月前的就不读了
{
string q;
in>>q;
int dday=(q[0]-'0')*10 (q[1]-'0');
int dmonth=(q[2]-'0')*10 (q[3]-'0');
int dyear=(((q[4]-'0')*10 (q[5]-'0'))*10 (q[6]-'0'))*10 (q[7]-'0');
Time tem(dyear,dmonth,dday);
Time now;
now.loadtime();
if(now>tem) continue;
a.tic.push_back(q);
}
return in;
}
ostream&operator<<(ostream&out,User&a)
{
out<<a.name<<' '<<a.id<<' '<<a.phone<<' '<<a.key<<' '<<' '<<a.ban<<' '<<a.tic.size()<<endl;
for(auto po=a.tic.begin();po!=a.tic.end();po ) out<<*po<<' ';
return out;
}
/*
int main()
{
User demo;
cin>>demo;
cout<<demo;
}
*/
/*
int main()
{
string name,id,phone;
cin>>name>>id>>phone;
User demo(name,id,phone);
cout<<demo.getname()<<endl;
cout<<demo.getid()<<endl;
cout<<demo.getphone()<<endl;
cin>>phone;
demo.setph(phone);
cout<<demo.getphone()<<endl;
}
*/
/*
int main()
{
User demo;
int a;
cin>>a;
demo.buytic(a);
cin>>a;
demo.buytic(a);
vector<int> w=demo.gettic();
for(auto po=w.begin();po!=w.end();po )cout<<*po<<endl;
cin>>a;
demo.del(a);
w=demo.gettic();
for(auto po=w.begin();po!=w.end();po )cout<<*po<<endl;
}*/
class Baseque //查询类
{
protected:
//12306所有的都具有唯一性。
vector<Station> station;//列车里的int(站台编号)对应station的int;
map<string,int>natosta;
vector<Train> train;
map<string,int>checitotrain;
// vector<User> user;
// map<string,int> idtouser;
// vector<Tick> tick;
// map<int,int> nutotic;
public:
Baseque(){station.clear();natosta.clear();train.clear();checitotrain.clear();load();}
void czcc(string a,int b,int d);
void cxcx(string a);
bool cxyp(string a,string b,int c);
void load();
void save();
//void insert()
~Baseque(){save();}
};
/*void Baseque;;insert()
{
Train tem2;
while( cin>>tem2)
{
cout<<-2; //手动调试点
if(tem2.gettr()=="$$") continue;
train.push_back(tem2);
checitotrain.insert(make_pair(tem2.gettr(),train.size()-1));
}
}*/
void Baseque ::czcc(string a,int b,int d)
{
vector<piao>w=station[natosta[a]].quecheci();
for(auto po=w.begin();po!=w.end();po )
{
vector<Zt> q= train[checitotrain[po->name]].getzt();
for(auto pi=q.begin();pi!=q.end();pi )
{
if(a==pi->getsta())
{
if(pi->getarr()==b||b==0||pi->getlea()==d||d==0)
{
cout<<po->name<<endl;
if(pi!=q.begin())
{
q.begin()->printl();
// cout<<1<<endl;
if(pi==q.end()-1)
{
(q.end()-1)->printa();
//cout<<2<<endl;
cout<<endl;
}
else
{
pi->print();
// cout<<endl;
(q.end()-1)->printa();
// cout<<3<<endl;
}
cout<<endl;
}
else
{
q.begin()->printl();
(q.end()-1)->printa();
cout<<endl;
}
cout<<endl;
}
}
// pi->print();
}
// cout<<endl;
}
}
void Baseque ::cxcx(string a) //车次查询
{
if(checitotrain.find(a)==checitotrain.end())
{
cout<<"NO Train"<<endl;
return ;
} //查不到不打印
vector<Zt> w=train[checitotrain[a]].getzt();
for(auto po=w.begin();po!=w.end();po )
{
cout<<station[natosta[po->getsta()]].getname()<<' ';
if(po!=w.begin()&&po!=w.end()-1)
{
po->print();
//cout<< po->getleave().first<<' '<<po->getleave().first;
}
else if(po==w.begin())
{
cout<< po->getleave().first<<' '<<po->getleave().first;
}
else cout<<po->getarrive().first<<' '<< po->getarrive().second<<' ';
}
cout<<endl;
}
bool Baseque :: cxyp(string a,string b,int riqi)
{
auto w=station[natosta[a]].quecheci();
auto v=station[natosta[b]].quecheci(); //vector<pair<string,int>> checi
set<piao>tem;
vector<piao>temp;
temp.clear();
for(auto po=w.begin();po!=w.end();po ) tem.insert(*po);
for(auto po=v.begin();po!=v.end();po )
{
if(tem.insert(*po).second==0) temp.push_back(*po);
}
if(temp.size()==0)
{
cout<<"No ticket"<<endl;
return 0 ;
}
for(auto po=temp.begin();po!=temp.end();po )
{
auto x= train[checitotrain[po->name]].getzt();
int mini=po->sum[riqi];
int ss=train[checitotrain[po->name]].cxyp(a,b,riqi);
mini=min(mini,ss);
cout<<train[checitotrain[po->name]].gettr()<<endl;;
for(auto pi=x.begin();pi!=x.end();pi ) //336
{
//cout<<s
pi->print();
}
cout<<mini<<endl;
}
return 1;
}
void Baseque::load()
{
int x,y,n;
ifstream in1("station.txt",ios::in);
in1>>n;
while( n--)
{
Station tem1;
in1>>tem1;
// cout<<-1; 手动调试点
if(tem1.getname()=="$$") continue;
station.push_back(tem1);
natosta.insert(make_pair(tem1.getname(),station.size()-1));
// cout<<1;
}
in1.close();
ifstream in2("train.txt",ios::in);
in2>>n;
while(n-- )
{
Train tem2;
in2>>tem2;
// cout<<-2; //手动调试点
if(tem2.gettr()=="$$") continue;
train.push_back(tem2);
checitotrain.insert(make_pair(tem2.gettr(),train.size()-1));
}
in2.close();
}
void Baseque::save()
{
ofstream out1("station.txt",ios::out);
out1<<station.size()<<endl;
for(auto po=station.begin();po!=station.end();po )
out1<<*po<<endl;
out1.close();
ofstream out2("train.txt",ios::out);
out2<<train.size()<<endl;
for(auto po=train.begin();po!=train.end();po )
out2<<*po<<endl;
out2.close();
}
/*
int main()
{
Baseque demo;
cin>>demo;
cout<<demo;
}
*/
/*
int main()
{
Baseque demo;
string a;
int c;
int b;
cin>>a>>b>>c;
demo.czcc(a,b,c);
cin>>a>>b>>c; //一天分四个时段查询。5就查不到
demo.czcc(a,b,c);
}*/
/*
int main()
{
Baseque demo;
string a;
int c;
int b;
cin>>a;//>>b>>c;
demo.cxcx(a);
cin>>a;//>>b>>c;
demo.cxcx(a);
}
*/
/*
int main()
{
Baseque demo;
string a,b;
cin>>a>>b;
demo.cxyp(a,b);
}
*/
/*
int main()
{
Baseque demo;
}*/
class Client:public Baseque
{
protected:
vector<User> user;
map<string,int> idtouse;
vector<Tick>tick;
map<string,int> hashtotick;
int now;//用于记录当前用户
string now2;
public:
Client(){load2();}
void load2();
void save2();
bool buytic(string a,string b,int c);
void reback();
void replacetic();
virtual void login();
void setphone(string a);
void printmp();
~Client(){save2();}
};
void Client::printmp()
{
auto ww=user[now].gettic();
for(auto po=ww.begin();po!=ww.end();po )
{
cout<<po-ww.begin() 1<<endl;
tick[ hashtotick[*po]].print();
}
}
bool Client::buytic(string a,string b,int c) //先查后买,查不到不能买。
{
if(!(cxyp(a,b,c))){cout<<"无票"<<endl;return 0;}
if(user[now].getboupiao()>5||user[now].getban())
{
cout<<"购票限制"<<endl;
return 0;
}
else
{
string id;
cin>>id;
pair<int,int>www=train[checitotrain[id]].buytic(a,b,c);
station[natosta[a]].buytic(a,c);
Time no1,no2;
no1.loadtime();
no2.loadtime();
no2.seth(www.first,www.second);
if(no2.getday()<c) no2.setmonth(no2.getmonth() 1);
Tick tem(no1,no2,a,b,now2,id);
tick.push_back(tem);
hashtotick.insert(make_pair(tem.getname(),tick.size()-1));
user[now].buytic(tem.getname());
}
return 1;
}
void Client::reback() //先查后买,查不到不能买。
{
printmp();
string id=now2;
int n;
cout<<"退哪一张票"<<endl;
cin>>n;
n=n-1;
auto ww=user[now].gettic();
string a=tick[ hashtotick[ww[n]]].getfrom();
cout<<1<<endl;;
string b=tick[ hashtotick[ww[n]]].getto();
cout<<2<<endl;;
int c=tick[ hashtotick[ww[n]]].getlea().getday();
cout<<3<<endl;;
train[checitotrain[id]].reback(a,b,c);
cout<<4<<endl;;
string e=tick[ hashtotick[ww[n]]].getna();
station[natosta[a]].rebac(e,c);
cout<<5<<endl;;
// tick.erase(hashtotick[ww[n]] tick.begin());
}
void Client::replacetic()
{
string a,b,id;
int c;
cin>>a>>b>>c;
if( buytic(a,b,c))
{
cin>>a>>b>>c;
reback();
}
}
void Client::setphone(string a)
{
user[now].setph(a);
}
void Client::login()
{
string phone;
string key;
while(cin>>phone>>key)
{
for(auto po=user.begin();po!=user.end();po )
{
if(po->getphone()==phone)
if(po->getkey()==key)
{
cout<<"Login prosperity"<<endl;
now=po-user.begin();
now2=po->getid();
return ;
}
}
cout<<"Wrong password"<<endl;
}
}
void Client::load2()
{
ifstream in("user.txt",ios::in);
int n;
if(!in) return ;
in>>n;
while(n--)
{
User tem;
in>>tem;
user.push_back(tem);
idtouse.insert(make_pair(tem.getname(),user.size()-1));
}
in.close();
ifstream in2("tick.txt",ios::in);
if(!in2) return ;
in2>>n;
while(n--)
{
Tick tem;
in2>>tem;
if(tem.getname()=="$$$") continue;
tick.push_back(tem);
hashtotick.insert(make_pair(tem.getname(),tick.size()-1));
}
in.close();
}
void Client::save2()
{
ofstream out("user.txt",ios::out);
out<<user.size()<<endl;
for(auto po=user.begin();po!=user.end();po ) out<<*po<<endl;
out.close();
ofstream out2("tick.txt",ios::out);
stringstream sss;
Time now;
now.loadtime();
string temp;
sss<<now.getyear()<<"年"<<now.getmonth()<<"月"<<now.getday()<<"日";
sss>>temp;
ofstream out3(temp,ios::out); //做过的车,就存到日志文件不在读取。
int sum=0;
for(auto po=tick.begin();po!=tick.end();po )
{
if(now>po->getlea())
{
out3<<*po<<endl;
}
else sum ;
}
out3.close();
out2<<sum<<endl;
for(auto po=tick.begin();po!=tick.end();po )
{
if(now>po->getlea()) continue;
out2<<*po<<endl;
}
out2.close();
}
/*
int main()
{
Client demo;
//demo.login();
}*/
/*int main()
{
Client demo;
demo.login();//登陆密码18053176044 123456
string a,b;
int riqi;
cin>>a>>b>>riqi;
demo.buytic(a,b,riqi);
demo.cxyp(a,b,riqi);
}*/
/*
int main()
{
Client demo;
demo.login();
string a,b;
int riqi;
cin>>a>>b>>riqi;
demo.buytic(a,b,riqi);
demo.reback();
demo.cxyp(a,b,riqi);
}*/
class Admin:public Client
{
public:
void login(){}
void insertsta();
bool delsta(string a);
void setsta(string a);
void inserttr();
bool deltr(string a);
void settr(string a);
};
void Admin:: insertsta()
{
Station tem1;
cin>>tem1;
station.push_back(tem1);
natosta.insert(make_pair(tem1.getname(),station.size()-1));
}
bool Admin::delsta(string a)
{
for(auto po=station.begin();po!=station.end();po )
if(po->getname()==a)
{
vector<piao> ww=po->quecheci();
for(auto pi=ww.begin();pi!=ww.end();pi )
train[checitotrain[pi->name]].del(a);
station.erase(po);
return 1;
}
cout<<"无此车站"<<endl;
return 0;
}
void Admin::setsta(string a)
{
if(!delsta(a))return ;
insertsta();
return ;
}
void Admin::inserttr()
{
Train tem2;
cin>>tem2;
train.push_back(tem2);
checitotrain.insert(make_pair(tem2.gettr(),train.size()-1));
return ;
}
bool Admin::deltr(string a)
{
for(auto po=train.begin();po!=train.end();po )
if(po->gettr()==a)
{
vector<Zt> ww=po->getzt();
for(auto pi=ww.begin();pi!=ww.end();pi )
station[natosta[pi->getsta()]].del(a);
train.erase(po);
return 1;
}
cout<<"无此高铁"<<endl;
return 0;
}
void Admin::settr(string a)
{
if(!deltr(a))return ;
inserttr();
}
/*
int main()
{
Admin demo;
demo.insertsta();
string a;
cin>>a;
demo.delsta(a);
// cout<<1<<endl;
demo.insertsta();
cin>>a;
demo.setsta(a);
// cout<<2<<endl;
}*/
/*
int main()
{
Admin demo;
demo.inserttr();
}*/
/*
int main()
{
Admin demo;
demo.inserttr();
string a;
cin>>a;
demo.deltr(a);
}*/
/*
int main()
{
Admin demo;
demo.inserttr();
string a;
cin>>a;
demo.settr(a);
// cout<<2<<endl;
}
*/