设为首页 收藏本站
查看: 1404|回复: 0

[经验分享] 华为练习 6 地铁最佳路径

[复制链接]

尚未签到

发表于 2016-6-6 11:02:45 | 显示全部楼层 |阅读模式
  错一半的用例,有空再检查吧
  检测了半天,修改了一些问题后,还是没通过,唉,说起来都是泪啊。
  题目也没说清楚一些问题。唉,改了很多东西,却没有多通过一个用例。
  

#include <map>
#include <set>
using namespace std;
struct stop{
unsigned int next[100];//最大有100个下一站,可连通
bool paased;//每次前往下一战时,先判断下一站是否已通过,若为通过则将其加入oldstop
int nnum;//可连通数量
int lnum;//线路数量
unsigned int LineNo[100];//所在线路的id
unsigned int path[100][100];//对于每条路径。。。我只保存前一个值是不够的。。。可能有多条路径,最多100条
int pnum;//路径数量
//int paassN;//
};
map<unsigned int,stop> allstop;
unsigned int oldstop[1000];
unsigned int newos[1000];//用来替换正在计算中的起点站
int newosn;//总起点暂时总数
int oldn;//起点总数
int passN;//结果站点总数
//int ps;//路径总数
//int newps;//新路径暂时总数
//unsigned int path[1000][100];
//unsigned int npath[1000][100];
/*******************************************************************************************************************
函数说明: 增加某条地铁线路
函数原型: void AddLine(unsigned int LineNo, unsigned int StationNum ,unsigned  int *pStationArray);
输入参数:
LineNo        地铁线路号;
StationNum    该条地铁线中的站点数目,由调用者保证不小于2;
pStationArray 该条地铁线的所有站点信息,pStationArray指向的存储空间在函数外会被释放,请自行申请存储空间;
输出参数: 无
返回值  : 无
********************************************************************************************************************/
void AddLine(unsigned int LineNo, unsigned int StationNum ,unsigned  int *pStationArray)
{
/* 在这里实现功能 */
//假设,对与 1 ,2, 1的环线线路,如何进行判断,站台数是2。。。
unsigned int p = 0 ;
unsigned int start = *pStationArray;
unsigned int before = *pStationArray;
map<unsigned int,stop>::iterator t;
for(int i = 0 ; i < StationNum ; i++){
if(allstop.count(*pStationArray)){//如果与其他线路交叉
t = allstop.find(*pStationArray);
t->second.LineNo[t->second.lnum++] = LineNo ;
if( i == 0){
before = *pStationArray++;
continue;
}
}else{
stop news;
news.LineNo[0] = LineNo ;
news.lnum = 1;
news.paased = false;
news.nnum = 0;
news.pnum = 0;
allstop.insert(pair<unsigned int,stop>(*pStationArray , news));
}
if(i > 0){
t = allstop.find(before);
t->second.next[t->second.nnum++] = *pStationArray;
t = allstop.find(*pStationArray) ;
t->second.next[t->second.nnum++] = before;
}
before = *pStationArray++;
}
if( start == *pStationArray) {//即为环,这里的stationnum是多少就是多少,不重复包含初始站和终点站
t->second.next[t->second.nnum++] = start ;
t = allstop.find(start);
t->second.next[t->second.nnum++] = before ;
}
return;
}
/*********************************************************************************************************************
函数说明:计算从起点站到终点站的最短路线长度
函数原型:int CalcMinPathLen(unsigned int SrcStation, unsigned int DesStation);
输入参数:
SrcStation  起点站;
DesStation 终点站;
输出参数:无
返回值  :
起点站到终点站的最短路线长度
-1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等)
**********************************************************************************************************************/
bool gonext(unsigned int DesStation){
map<unsigned int,stop>::iterator p;
map<unsigned int,stop>::iterator next;
newosn=0;
passN++;
//newps=0;
for(int i=0;i<oldn;i++){
p =allstop.find(oldstop);
for(int j=0;j<p->second.nnum;j++){
next = allstop.find(p->second.next[j]);
if(!next->second.paased){
//next->second.paased = true;//一次前进过程中,可以从不同的方向到达同一点,但是,不能从回到原来的点
int pathnun=p->second.pnum;
for(int l=0;l<pathnun;l++){
for(int k=0;k < passN - 1;k++){
next->second.path[next->second.pnum][k] = p->second.path[l][k];
}
next->second.path[next->second.pnum++][passN-1] = next->first;
//npath[newps][passN-1] = next->first;
//next->second.path[next->second.pnum++] = path[newps++];
}
//next
newos[newosn++] = next->first;
}
}
}
oldn = newosn;
//ps = newps;
int nn=0;
for(int i=0;i < oldn;i++){
p = allstop.find(newos);
if(!p->second.paased){
oldstop[nn++] = newos ;
p->second.paased= true ;
}
}
oldn = nn;
//for (int i=0;i < ps;i++){
//for(int j=0;j < passN ;j++){
//path[j] = npath[j];
//}
//}
for (int i=0;i<oldn;i++){
if(oldstop == DesStation)
return false;
}
return true;
}
int CalcMinPathLen(unsigned int SrcStation, unsigned int DesStation)
{
/* 在这里实现功能 */
if(SrcStation==DesStation)return -1;
if(!allstop.count(SrcStation)||!allstop.count(DesStation))return -1;
map<unsigned int ,stop>::iterator p;
p = allstop.begin();
for(int i=0; i< allstop.size();i++){//初始化一部分数据
p -> second.paased = false;
p -> second.pnum = 0;
p++;
}
p = allstop.find(SrcStation );
p->second.paased = true;
p->second.pnum=1;
oldn = 0;
oldstop[oldn++] = SrcStation ;
//path[0][0] = SrcStation;
passN = 0;
//ps = 0;
while(gonext(DesStation));//寻找路径
p = allstop.find(DesStation);
int k =0;
int m =0 ;
int fuc = p->second.pnum ;
unsigned int fuck[100];
///*
for(int L =0;L < p->second.pnum;L++){
fuc --;
for(int i = 0;i < fuc;i++){//还要字典序排序?
if( p->second.path[k] > p ->second.path[i+1][k]){
for( m=0;m<passN;m++)
fuck[m] = p->second.path[m];
for( m =0; m<passN;m++)
p->second.path[m] = p->second.path[i+1][m];
for( m =0;m<passN;m++)
p->second.path[i+1][m] = fuck[m];
}else{
for ( int ff=0;ff< passN;ff++){
if( p->second.path[k] > p ->second.path[i+1][k]){
for( m=0;m<passN;m++)
fuck[m] = p->second.path[m];
for( m =0; m<passN;m++)
p->second.path[m] = p->second.path[i+1][m];
for( m =0;m<passN;m++)
p->second.path[i+1][m] = fuck[m];
break;
}
}
}
}
}//*/
return passN;
}


/**********************************************************************************************************
函数说明:输出从起点站到终点站的最短路线
函数原型:int SearchMinPathes(unsigned int SrcStation,
unsigned int DesStation,
unsigned int* pPathNum,
unsigned int* pPathLen,
unsigned int **ppPathes);
输入参数:
SrcStation 起点站;
DesStation 终点站;
Output Param
pPathNum 最短路线条数;
pPathLen  最短路线长度;
ppPathes 存储最短路线的内存地址,内存空间在本函数内申请,调用者释放,内存空间的存储格式请见PPT要求;
返回值  :
0 :成功
-1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等)
************************************************************************************************************/
int SearchMinPathes(unsigned int SrcStation,
unsigned int DesStation,
unsigned int* pPathNum,
unsigned int* pPathLen,
unsigned int **ppPathes)
{
/* 在这里实现功能 */
map<unsigned int,stop>::iterator p;
int r = CalcMinPathLen(SrcStation,DesStation);
if(r==-1)return -1;
else{
*pPathNum = passN;
p = allstop.find(DesStation);
r = p->second.pnum;
*pPathLen = r;
//r*=passN;
unsigned int  *save = (unsigned int*)malloc(sizeof(unsigned int)*r*passN);
*ppPathes = save;
for(int i=0;i<r;i++){
for(int j=0;j<passN;j++)
*save++ = p->second.path[j];
}

}
return 0;
}

/*************************************************************************************************
函数说明:输出从起点站到终点站的最优路线
函数原型:int SearchBestPathes(unsigned int SrcStation,
unsigned int DesStation,
unsigned int *pPathNum,
unsigned int* pPathLen,
unsigned int** ppPathes);
输入参数:
SrcStation 起点站;
DesStation 终点站;
Output Param
pPathNum 最优路线条数;
pPathLen  最短路线长度;
ppPathes 存储最短路线的内存地址,内存格式见下图,内存空间在本函数内申请,调用者释放;
返回值 :
0:成功
-1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等)
**************************************************************************************************/
int SearchBestPathes(unsigned int SrcStation,
unsigned int DesStation,
unsigned int *pPathNum,
unsigned int* pPathLen,
unsigned int** ppPathes)
{
/* 在这里实现功能 */
int mini = 999;//最短路线
int changes = 0;
int all = 0;
int pathnum = 0 ;
int pathchange[100];
set<unsigned int> oldline;
set<unsigned int>::iterator t;
map<unsigned int,stop>::iterator p;
map<unsigned int,stop>::iterator last;
map<unsigned int,stop>::iterator now;
map<unsigned int,stop>::iterator start;
int r = CalcMinPathLen(SrcStation,DesStation);\
if(r == -1)return -1;
else{
p = allstop.find(DesStation);
start = allstop.find(SrcStation);
all = p->second.pnum;
for(int i=0;i<all;i++){
last = start;
changes = 0;
for(int j=0;j<last->second.lnum;j++){
oldline.insert(last->second.LineNo[j]);//将第一个点可能的线路记录下来
}
for(int j=0;j<passN;j++){
now = allstop.find( p->second.path[j]);
int n = oldline.size();
t = oldline.begin();
bool htheline=false;
for (int k=0; k < n ;k++){
htheline = false ;
for(int m=0;m<now->second.lnum;m++){
if( *t == now->second.LineNo[m]){
htheline =true;
break;
}
}
if(!htheline){
t = oldline.erase(t);
}else{
t++;
}
}
if(oldline.size()==0){//为空时,即必须要换车了,将这个点的所有可能线路保存下来
changes++;
for(int j=0;j<last->second.lnum;j++){
for(int k=0;k<now->second.lnum;k++)
if(last->second.LineNo[j]==now->second.LineNo[k])
oldline.insert(last->second.LineNo[j]);//将从前一站到这一站可能使用的线路记录下来。
}
}else{
;//继续以剩余的线路继续前行
}
last = now;
}
pathchange = changes ;
oldline.clear();
}
mini = 999;
for(int i=0; i<all;i++){
mini = mini<pathchange?mini:pathchange;//编程之美
}
//oldline.clear();
for(int i=0;i<all;i++){
if(pathchange==mini)
pathchange[pathnum++] = i;//获得最佳路线的数量和序号
}
*pPathNum = pathnum;
*pPathLen = passN ;
unsigned int  *save = (unsigned int*)malloc(sizeof(unsigned int)*pathnum*passN);
*ppPathes = save;
for(int i=0;i<pathnum;i++){
for(int j=0;j<passN;j++)
*save++ = p->second.path[pathchange][j];
}
}
return 0;
}
/*************************************************************************************************
函数说明:清空所有的线路信息
函数原型:void Clear();
输入参数:无
输出参数:无
返回值  :无
**************************************************************************************************/
void Clear()
{
/* 在这里实现功能 */
allstop.clear();

return ;
};


  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-226996-1-1.html 上篇帖子: [华为机试题]最大连续递增子串 下篇帖子: c++ 华为练习五 内存文件系统
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表