蓝桥杯-地铁换乘

#include<stdio.h>
#include<string.h>

/**变量声明********************/
#define MAX_sta 1000
#define MAX_line 100
#define MAX_mode 200

struct {
char line[MAX_line][20];/*线号*/
int steat[MAX_line];/*与线号对应的站号*/
char data[30];/*站名*/
int mark;/*标记,2为未赋值,0为已赋值未记录,1为已记录*/
}stations[MAX_sta];

struct{
char linename[20];//线名
int RMB;//单票钱
char linego[MAX_line][20];//联票
int money[MAX_line];//联票钱
}price[MAX_mode];

int Total_stations=0;//站的总数
int Total_lines=0;//线的总数

int crosslap[MAX_sta];//存放交点下标
char begin[MAX_line][20];//开始线名
char end[MAX_line][20];//结束线名
char join[1000][MAX_line][20];//所有可能线路
char fu[7/*MAX_line*/][20];//临时线路
int r=0;//方便控制join的数量
/**函数声明********************/

int findstation(char *p);/*判断是否存在相同值的结点*/

int start_stations(char *a);//站点初始化

int start_price(char *b);//价格初始化

void many(void);//寻找交叉点

int findnumer( char *p);//给出线名找线号

void f(int n);//复杂线路设计

void plan(int locp, int locq);//线路设计的开始

void qian();//算钱

int check(char *p,int n);//检查

/*函数******************/

int start_stations(char *a)
{
FILE *fp=fopen(a,"rb");
if(fp == NULL)
{
printf("文件打开失败!");
return 0;
}

char p[30];//临时站名
int i,k;
int len=0;
int m=1;
int h=0;
char q[30];//临时线名
memset(p,0,sizeof(p));
memset(q,0,sizeof(q));
fgets(q,40,fp);//文件的开始,是一个线名
len=strlen(q);
q[len-2]='\0';

for(i=0;i<MAX_sta;i++)
stations[i].mark=2;

while(!feof(fp))
{
memset(p,0,sizeof(p));
fgets(p,40,fp);
len=strlen(p);
p[len-2]='\0';
if(strlen(p) == 0)
{
fgets(q,40,fp);//获取线名
len=strlen(q);
q[len-2]='\0';
continue;
}
h=findstation(p);//判断是否创建
if( h == -1 )
{
strcpy( stations[Total_stations].data , p );
stations[Total_stations].mark=0;
strcpy( stations[Total_stations].line[0], q);
stations[Total_stations].steat[0]=m;
m++;
Total_stations++;
}
else
{
for(k=0; strlen(stations[h].line[k]) != 0; k++)
;
strcpy(stations[h].line[k],q);
stations[h].steat[k]=m;
m++;
}
}
fclose(fp);
return 1;

}//start_stations

int findstation(char *p)/*判断是否存在相同值的结点*/
{
int i;
for(i=0;stations[i].mark !=2 ;i++)
if(strcmp(p,stations[i].data) == 0)return i;/*表示该值的结点存在的结点位置*/
return -1;/*表示该值的结点不存在,未创建*/
}/*findstation*/

int start_price(char *b)
{
FILE *fp=fopen(b,"rb");
if( fp == NULL )
{
printf("文件打开失败!");
return 0;
}

char p[30],q[30],g[30];
memset(p,0,sizeof(p));
memset(q,0,sizeof(q));
memset(g,0,sizeof(g));
int len=0;
int i,j,r;
int count=0;


while(fscanf(fp,"%s",p) != -1)
{
len=strlen(p);
for(i=0; i<len; i++)
if(p[i] == 44)
break;
if(i == len)//不存在","
{
strcpy( price[Total_lines].linename , p);
memset(p,0,sizeof(p));
fscanf(fp,"%s",g);
len=strlen(g);
for(j=0; j<len; j++)
{
count*=10;
count+=(g[j]-48);
}
price[Total_lines].RMB=count;
/*重新赋值*/
count=0;
memset(p,0,sizeof(p));
Total_lines++;
memset(g,0,sizeof(g));
}
else if( i != len)//存在","
{
strcpy(q,&p[i+1]);

fscanf(fp,"%s",g);
len=strlen(g);
for(j=0; j<len; j++)
{
count*=10;
count+=(g[j]-48);
}

for(r=0; r<Total_lines; r++)
if( strncmp( price[r].linename , p ,i) == 0)
break;
for(j=0; strlen( price[r].linego[j]) !=0;j++)
;
strcpy( price[r].linego[j] , q);
price[r].money[j]=count;

for(r=0; r<Total_lines; r++)
if( strcmp( price[r].linename , q) == 0)
break;
for(j=0; strlen( price[r].linego[j]) !=0;j++)
;
strncpy( price[r].linego[j] ,p ,i);
price[r].money[j]=count;
/*重新赋值*/
count=0;
memset(p,0,sizeof(p));
memset(q,0,sizeof(q));
memset(g,0,sizeof(g));
}
}

fclose(fp);

return 1;
}

void many(void)//寻找交叉点
{
int i,j=0;
for(i=0; stations[i].mark != 2; i++)
if( strlen( stations[i].line[1] ) !=0)
{
crosslap[j]=i;
j++;
}
}

int findnumber( char *p)
{
int i;
for(i=0; i<Total_lines; i++)
{
if( strcmp(p,price[i].linename) == 0)
return i;
}
return -1;
}

int check(char *p,int n)
{
int i;

for(i=0;i<n;i++)
if( strcmp(p,fu[i]) == 0)
return 0;

return 1;
}
void f( int n)
{
int i=0,j=0,t=0,w1=0,w2=0;
int k=0;
int number=findnumber(fu[n-1]);
for(i=0;strlen( price[number].linego[i] ) !=0; i++)//扫描联票
{
if( check( price[number].linego[i],n ) == 1)
{
strcpy( fu[n] , price[number].linego[i] );
for(j=0; strlen(end[j]) !=0; j++)
if( strcmp(end[j] , fu[n]) == 0)//递归的停止条件
{
for(k=0; k<=n; k++)
strcpy(join[r][k],fu[k]);
for(w1=0; w1<r; w1++)
{
for(w2=0; w2<Total_lines; w2++)
if( strcmp(join[w1][w2] ,join[r][w2]) !=0)
break;
if( w2 == Total_lines )
break;
}
if(w1 == r)
{
r++;
t=1;
}
else
{
for(w2=0; w2<Total_lines; w2++)
memset(join[r][w2],0,sizeof(join[r][w2]));
}
}
if(t == 1)
{
t=0;
continue;
}
f(n+1);
}
}
int s=0,h=0;
for(i=0,t=0; crosslap[i]; i++)//扫描交叉点
for(h=0; strlen(stations[crosslap[i]].line[h]) != 0; h++)
{
if( strcmp( stations[crosslap[i]].line[h], fu[n-1]) == 0)
for(s=0; strlen(stations[crosslap[i]].line[s]) != 0; s++)
if(check(stations[crosslap[i]].line[s] , n) ==1)//递归的停止条件
{
strcpy(fu[n],stations[crosslap[i]].line[s]);
for(j=0; strlen(end[j]) !=0; j++)
if( strcmp(fu[n],end[j]) == 0 )
{
for(k=0; k<=n; k++)
strcpy(join[r][k], fu[k]);
for(w1=0; w1<r; w1++)
{
for(w2=0; w2<Total_lines; w2++)
if( strcmp(join[w1][w2] ,join[r][w2]) !=0)
break;
if(w2 == Total_lines)
break;
}
if(w1 == r)
{
r++;
t=1;
}
else
{
for(w2=0; w2<Total_lines; w2++)
memset(join[r][w2],0,sizeof(join[r][w2]));
}
}
if(t == 1)
{
t=0;
continue;
}
f(n+1);
}
}
}

void plan(int locp, int locq)
{
int i,j,t=0;
for(i=0,j=0; strlen(stations[locp].line[i]) !=0; i++)
{
strcpy(begin[j],stations[locp].line[i] );
j++;
}
for(i=0,j=0; strlen( stations[locq].line[i]) !=0; i++)
{
strcpy(end[j],stations[locq].line[i]);
j++;
}

for(i=0; strlen(begin[i]) != 0; i++)
{
strcpy(fu[0],begin[i]);
for(j=0; strlen(end[j]) != 0; j++)
if(strcmp( end[j], fu[0]) == 0)
{
strcmp(join[r][0],fu[0]);
r++;
t=1;
}
if( t== 1)
continue;
f(1);
}
for(int s=r-1;s>=0;s--)
{
printf("s=%d ",s);
for(i=0;strlen(join[s][i]) !=0;i++)
printf("%s-",join[s][i]);
printf("\n");
}
}

void qian()
{
int cost[2];
char newh[MAX_line][30];
char oldh[MAX_line][30];
int n=1000000,m=1000000,t=-1;
int i=0,j=0,k=0,s=0;
int h=0;
cost[0]=1000000;
memset(newh,0,sizeof(newh));
memset(oldh,0,sizeof(oldh));

for(i=0;i<r;i++)
{
memset(newh,0,sizeof(newh));
j=1;
cost[1]=0;
s=0;
while(j<Total_lines)
{
n=1000000;
m=1000000;
t=findnumber(join[i][j]);
for(k=0; strlen(price[t].linego[k]) != 0; k++)
{
if(strcmp( price[t].linego[k],join[i][j-1]) == 0)
n=price[t].money[k];
if(strcmp( price[t].linego[k],join[i][j+1]) == 0)
m=price[t].money[k];
}
if(n<m)
{
cost[1]+=n;
strcpy(newh[s] , join[i][j-1]);
s++;
strcpy(newh[s],"#");
s++;
strcpy( newh[s],join[i][j]);
s++;
j+=2;
}
else if(n>m)
{
cost[1]+=(m+price[findnumber(join[i][j-1])].RMB);
strcpy( newh[s],join[i][j-1]);
s++;
strcpy(newh[s],"#");
s++;
strcpy(newh[s],join[i][j+1]);
s++;
j+=3;
}
else if(n == m)
{
cost[1]+=(price[findnumber(join[i][j-1])].RMB+price[findnumber(join[i][j])].RMB);
strcpy(newh[s],join[i][j-1]);
s++;
strcpy(newh[s],join[i][j]);
s++;
j+=2;
}
}
if(cost[1]<cost[0])
{
h=i;
cost[0]=cost[1];
memset(oldh,0,sizeof(oldh));
for(k=0;strlen(newh[k]) !=0; k++)
strcpy(oldh[k],newh[k]);
memset(newh,0,sizeof(newh));
}
}
printf("%d ,%d\n",cost[0],h);
for(i=0; strlen(oldh[i])!=0; i++)
{
if(strcmp(oldh[i+1],"#") == 0)
{
printf("-(%s,",oldh[i]);
i+=2;
printf("%s)",oldh[i]);
}
else
printf("-%s",oldh[i]);
}
printf("\n");
}

/**********************/
void main()
{
char a[50]="stations.txt";
char b[50]="price.txt";
start_stations(a);
start_price(b);
many();
char p[30],q[30];
memset(p,0,sizeof(p));
memset(q,0,sizeof(q));
scanf("%s",p);
int i;
for(i=0;p[i] != 44; i++)
;
strncpy(q,p,i);
int locp=findstation(q);
int locq=findstation(&p[i+1]);
plan(locp,locq);
qian();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值