• 简易的C语言地铁购票系统


    大致思路:

    将地铁线路的抽象问题转化为图上最短路径的具体问题,那么最大的难点如何抽象出来。

    1.用结构体存储每个站点的信息:包括编号、名称、所经过的线路;

    2.names数组存储每个不通过站点的名字,其下表对应着站点的标号,这样读取数据时,可以利用它保证每个站点不被重复构建;

    3.map二维数组存储每个站点间的距离;

    基本靠以上数据结构就可以将问题具体化了,然后就转为图上的路径规划问题,利用dfs等算法即可解决。

    效果展示(推荐dev进行代码运行):

    代码:

    纯C版本:

    #include <stdio.h>
    #include <string.h>
    
    // 站点信息 
    typedef struct Station{
    	char name[30]; // 站点名称 
    	int lines[20]; // 经过的线路 
    	int cnt;       // 线路数量 
    }Station; 
    Station stations[100];
    // 站点间收费
    double map[100][100];
    // 站点数量
    int staNum; 
    // 站点名称
    char names[100][30]; 
    // 标记是否访问过
    int visit[100]; 
    // 可选路线数量:
    int ansNum; 
    // 最优路线:
    int minLu[100];
    // 最优路线中站数量:
    int minCnt;
    // 最优价格:
    double minPrict; 
    // 当前线路:
    int nowLu[100];
    
    // 查找路线:
    void dfs(int id1, int id2, int ct, double cost){
    	int i, j;
    	if(id1 == id2){
    		printf("可选路线%d:
    ", ++ansNum);
    		for(i = 0; i < ct; i++){
    			if(i == 0)
    				printf("%s", names[nowLu[i]]);
    			else
    				printf(" -> %s", names[nowLu[i]]);
    			printf("(");
    			for(j = 0; j < stations[nowLu[i]].cnt; j++){
    				printf("%d,", stations[nowLu[i]].lines[j]);
    			}
    			printf(")");
    		}
    		printf("   [费用:%lf]
    ", cost);
    		// 是否最优:
    		if(cost < minPrict){
    			minCnt = ct;
    			minPrict = cost;
    			for(i = 0; i < ct; i++){
    				minLu[i] = nowLu[i];
    			}
    		} 
    	} 
    	for(i = 0; i < staNum; i++){
    //		printf("%d %d %lf %d
     ", id1, id2, map[id1][i], 0x3f3f3f3f, visit[i]);
    		if(i != id1 && map[id1][i] < 0x3f3f3f3f && visit[i] == 0){
    			visit[i] = 1;
    			nowLu[ct] = i;
    //			printf("%d %d %d %d %d ",id1, id2, i, ct, nowLu[ct]);
    			dfs(i, id2, ct + 1, cost + map[id1][i]);
    			visit[i] = 0;
    		}
    	} 
    	
    } 
    
    int main()
    {
    	// 读入文件:包含线路信息 
        FILE *fp; 
    	int i, j;  
    	int id2;
        fp = fopen("data.txt","r"); //需要创建a.txt文件,然后写入两个数据,空格隔开
    //    memset(map, 0x3f3f3f3f, sizeof(map)); 
    	for (i = 0; i < 100; i++){
    		for(j = 0; j < 100; j++){
    			map[i][j] = 0x3f3f3f3f;
    		}
    	} 
        // 站点数量 
        staNum = 0;
    	for(i = 1; i <= 5; i++){
    		printf("[%d号线] ", i);
    		while(1){
    			double f=0;
    		    char name1[30];
    		    char name2[30];
    		    fscanf( fp, "%s", &name1);
    		    // 每条线路结束符规定为# 
    		    if(name1[0] == '#'){
    		    	printf("
    ", i);
    		    	break;
    		    }
    		    	
    		    // 查找当前站点是否存在 
    		    int id1 = -1;
    			for(j = 0; j < staNum; j++){
    				 if(strcmp(name1, names[j]) == 0){
    				 	id1 = j;
    				 	break;
    				 }
    			}
    			// 如果当前站点不存在,则需要创建 
    			if(id1 == -1){
    				id1 = staNum; 
    				strcpy(names[id1], name1);
    //				stations[id1].name = name1; // 存入名字 
    				strcpy(stations[id1].name, name1);
    				stations[id1].lines[0] = i; // 存入线路 
    				stations[id1].cnt = 1;      // 所经过的线路 
    				staNum++;
    			} 
    			else{
    				if (stations[id1].lines[stations[id1].cnt-1] != i){ //考虑是否需要把当前所在线路标号(即线路几)存入该站点的lines
    					stations[id1].lines[stations[id1].cnt] = i;
    //					printf("||| i = %d, %s", i, name1);
    					stations[id1].cnt++;	
    				} 
    			}
    			// 读入数据: 
    		    fscanf( fp, "%s%lf", &name2, &f);
    		    // 查找当前站点是否存在 
    		    id2 = -1;
    			for(j = 0; j < staNum; j++){
    				 if(strcmp(name2, names[j]) == 0){
    				 	id2 = j;
    				 	break;
    				 }
    			}
    			// 如果当前站点不存在,则需要创建 
    			if(id2 == -1){
    				id2 = staNum;
    //				names[id2] = name2;
    				strcpy(names[id2], name2);
    //				stations[id2].name = name2; // 存入名字
    				strcpy(stations[id2].name, name2);  
    				stations[id2].lines[0] = i; // 存入线路 
    				stations[id2].cnt = 1;      // 所经过的线路 
    				staNum++;
    			} 
    			else{
    				if(stations[id2].lines[stations[id2].cnt-1] != i){
    					stations[id2].lines[stations[id2].cnt] = i;
    //					printf("[ i = %d, %d %s] ", i, stations[id2].cnt, name2);
    					stations[id2].cnt++;
    				}
    			}
    			// 加入权重:
    			map[id1][id2] = map[id2][id1] = f; 
    		    printf("%s->%s %lf  ", name1, name2, f);
    		}
    		printf("
    ");
    	} 
    //	for(int i = 0; i < staNum; i++){
    //		printf("%s ", stations[i].name);
    //		for(int j = 0; j < stations[i].cnt; j++){
    //			printf("%d,", stations[i].lines[j]);
    //		}
    //		printf("
    ");
    //	}
    //	printf("
    ");
    	// 打印矩阵:
    //	for (int i = 0; i < staNum; i++){
    //		for(int j = 0; j < staNum; j++){
    //			printf("%lf ", map[i][j]);
    //		}
    //		printf("
    ");
    //	} 
    	
    	fclose(fp);
    	
    	// 功能启动:
    	while(1){
    		// 输入需要查找的线路:
    		char n1[30];
    		char n2[30];
    		int i, j;
    
    		// 查找当前站点是否存在 
    	    int id1 = -1, id2 = -1;
    	    printf("请输入起始点和终点:
    ");
    		scanf("%s %s", n1, n2);
    		for(j = 0; j < staNum; j++){
    			 if(strcmp(n1, names[j]) == 0){
    			 	id1 = j;
    			 }
    //			 else{
    //			 	printf("%s %s
    ", n1, names[j]);
    //			 }
    			 if(strcmp(n2, names[j]) == 0){
    			 	id2 = j;
    			 }
    		}	 
    //		printf("id1 %s id2 %s
    ", n1, n2);
    //		printf("您查找的起始点和终点分别是: %s -> %s
    ", n1, n2);
        	if(id1 == -1 || id2 == -1){
        		printf("您输入的名称不存在!
    "); 
        		continue;
        	}
        	printf("您查找的起始点和终点分别是: %s -> %s
    ", n1, n2);
        	// 清空数组 
        	memset(visit, 0, sizeof(visit)); 
        	// 可选路线数量 
    		ansNum = 0; 
    		nowLu[0] = id1;  // 放入起点 
    		visit[id1] = 1;
    		minPrict = 0x3f3f3f3f; // 初始化最优价格 
        	dfs(id1, id2, 1, 0);   // 起点, 终点, 路线中数据点个数, 价格 
    		for(i = 0; i < minCnt; i++){
    			if(i == 0)
    				printf("最优路线:%s", names[minLu[i]]);
    			else
    				printf(" -> %s", names[minLu[i]]);
    			printf("(");
    			for(j = 0; j < stations[minLu[i]].cnt; j++){
    				printf("%d,", stations[minLu[i]].lines[j]);
    			}
    			printf(")");
    		}
    		printf("   [费用:%lf]
    ", minPrict);
        	printf("本次查找结束!!!
    
    ");
    	} 
        
        return 0;
    }
    

      

     C++版:

    #include <stdio.h>
    #include <string.h>
    
    // 站点信息 
    typedef struct Station{
    	char name[30]; // 站点名称 
    	int lines[20]; // 经过的线路 
    	int cnt;       // 线路数量 
    }Station; 
    Station stations[100];
    // 站点间收费
    double map[100][100];
    // 站点数量
    int staNum; 
    // 站点名称
    char names[100][30]; 
    // 标记是否访问过
    int visit[100]; 
    // 可选路线数量:
    int ansNum; 
    // 最优路线:
    int minLu[100];
    // 最优路线中站数量:
    int minCnt;
    // 最优价格:
    double minPrict; 
    // 当前线路:
    int nowLu[100];
    
    // 查找路线:
    void dfs(int id1, int id2, int ct, double cost){
    	if(id1 == id2){
    		printf("可选路线%d:
    ", ++ansNum);
    		for(int i = 0; i < ct; i++){
    			if(i == 0)
    				printf("%s", names[nowLu[i]]);
    			else
    				printf(" -> %s", names[nowLu[i]]);
    			printf("(");
    			for(int j = 0; j < stations[nowLu[i]].cnt; j++){
    				printf("%d,", stations[nowLu[i]].lines[j]);
    			}
    			printf(")");
    		}
    		printf("   [费用:%lf]
    ", cost);
    		// 是否最优:
    		if(cost < minPrict){
    			minCnt = ct;
    			minPrict = cost;
    			for(int i = 0; i < ct; i++){
    				minLu[i] = nowLu[i];
    			}
    		} 
    	} 
    	for(int i = 0; i < staNum; i++){
    //		printf("%d %d %lf %d
     ", id1, id2, map[id1][i], 0x3f3f3f3f, visit[i]);
    		if(i != id1 && map[id1][i] < 0x3f3f3f3f && visit[i] == 0){
    			visit[i] = 1;
    			nowLu[ct] = i;
    //			printf("%d %d %d %d %d ",id1, id2, i, ct, nowLu[ct]);
    			dfs(i, id2, ct + 1, cost + map[id1][i]);
    			visit[i] = 0;
    		}
    	} 
    	
    } 
    
    int main()
    {
    	// 读入文件:包含线路信息 
        FILE *fp;   
        fp = fopen("data.txt","r"); //需要创建a.txt文件,然后写入两个数据,空格隔开
    //    memset(map, 0x3f3f3f3f, sizeof(map)); 
    	for (int i = 0; i < 100; i++){
    		for(int j = 0; j < 100; j++){
    			map[i][j] = 0x3f3f3f3f;
    		}
    	} 
        // 站点数量 
        staNum = 0;
    	for(int i = 1; i <= 5; i++){
    		printf("[%d号线] ", i);
    		while(1){
    			double f=0;
    		    char name1[30];
    		    char name2[30];
    		    fscanf( fp, "%s", &name1);
    		    // 每条线路结束符规定为# 
    		    if(name1[0] == '#'){
    		    	printf("
    ", i);
    		    	break;
    		    }
    		    	
    		    // 查找当前站点是否存在 
    		    int id1 = -1;
    			for(int j = 0; j < staNum; j++){
    				 if(strcmp(name1, names[j]) == 0){
    				 	id1 = j;
    				 	break;
    				 }
    			}
    			// 如果当前站点不存在,则需要创建 
    			if(id1 == -1){
    				id1 = staNum; 
    				strcpy(names[id1], name1);
    //				stations[id1].name = name1; // 存入名字 
    				strcpy(stations[id1].name, name1);
    				stations[id1].lines[0] = i; // 存入线路 
    				stations[id1].cnt = 1;      // 所经过的线路 
    				staNum++;
    			} 
    			else{
    				if (stations[id1].lines[stations[id1].cnt-1] != i){
    					stations[id1].lines[stations[id1].cnt] = i;
    //					printf("||| i = %d, %s", i, name1);
    					stations[id1].cnt++;	
    				} 
    			}
    			// 读入数据: 
    		    fscanf( fp, "%s%lf", &name2, &f);
    		    // 查找当前站点是否存在 
    		    int id2 = -1;
    			for(int j = 0; j < staNum; j++){
    				 if(strcmp(name2, names[j]) == 0){
    				 	id2 = j;
    				 	break;
    				 }
    			}
    			// 如果当前站点不存在,则需要创建 
    			if(id2 == -1){
    				id2 = staNum;
    //				names[id2] = name2;
    				strcpy(names[id2], name2);
    //				stations[id2].name = name2; // 存入名字
    				strcpy(stations[id2].name, name2);  
    				stations[id2].lines[0] = i; // 存入线路 
    				stations[id2].cnt = 1;      // 所经过的线路 
    				staNum++;
    			} 
    			else{
    				if(stations[id2].lines[stations[id2].cnt-1] != i){
    					stations[id2].lines[stations[id2].cnt] = i;
    //					printf("[ i = %d, %d %s] ", i, stations[id2].cnt, name2);
    					stations[id2].cnt++;
    				}
    			}
    			// 加入权重:
    			map[id1][id2] = map[id2][id1] = f; 
    		    printf("%s->%s %lf  ", name1, name2, f);
    		}
    		printf("
    ");
    	} 
    //	for(int i = 0; i < staNum; i++){
    //		printf("%s ", stations[i].name);
    //		for(int j = 0; j < stations[i].cnt; j++){
    //			printf("%d,", stations[i].lines[j]);
    //		}
    //		printf("
    ");
    //	}
    //	printf("
    ");
    	// 打印矩阵:
    //	for (int i = 0; i < staNum; i++){
    //		for(int j = 0; j < staNum; j++){
    //			printf("%lf ", map[i][j]);
    //		}
    //		printf("
    ");
    //	} 
    	
    	fclose(fp);
    	
    	// 功能启动:
    	while(1){
    		// 输入需要查找的线路:
    		char n1[30];
    		char n2[30];
    		printf("请输入起始点和终点:
    ");
    		scanf("%s %s", n1, n2);
    		// 查找当前站点是否存在 
    	    int id1 = -1, id2 = -1;
    		for(int j = 0; j < staNum; j++){
    			 if(strcmp(n1, names[j]) == 0){
    			 	id1 = j;
    			 }
    //			 else{
    //			 	printf("%s %s
    ", n1, names[j]);
    //			 }
    			 if(strcmp(n2, names[j]) == 0){
    			 	id2 = j;
    			 }
    		}	 
    //		printf("id1 %s id2 %s
    ", n1, n2);
    //		printf("您查找的起始点和终点分别是: %s -> %s
    ", n1, n2);
        	if(id1 == -1 or id2 == -1){
        		printf("您输入的名称不存在!
    "); 
        		continue;
        	}
        	printf("您查找的起始点和终点分别是: %s -> %s
    ", n1, n2);
        	// 清空数组 
        	memset(visit, 0, sizeof(visit)); 
        	// 可选路线数量 
    		ansNum = 0; 
    		nowLu[0] = id1;  // 放入起点 
    		visit[id1] = 1;
    		minPrict = 0x3f3f3f3f; // 初始化最优价格 
        	dfs(id1, id2, 1, 0);   // 起点, 终点, 路线中数据点个数, 价格 
    		for(int i = 0; i < minCnt; i++){
    			if(i == 0)
    				printf("最优路线:%s", names[minLu[i]]);
    			else
    				printf(" -> %s", names[minLu[i]]);
    			printf("(");
    			for(int j = 0; j < stations[minLu[i]].cnt; j++){
    				printf("%d,", stations[minLu[i]].lines[j]);
    			}
    			printf(")");
    		}
    		printf("   [费用:%lf]
    ", minPrict);
        	printf("本次查找结束!!!
    
    ");
    	} 
        
        return 0;
    }
    

      

    数据:

    a b 4 b c 10 c d 7 d e 4 #
    f g 3 g c 8 c h 4 h i 1 i j 7 #
    k l 4 l m 7 m d 3 d n 2 n o 1 #
    p l 2 l q 1 q r 3 r s 5 s t 9 #
    u t 1 t v 9 v d 3 d w 7 w x 3 x y 2 #
    

      

  • 相关阅读:
    bzoj 1911: [Apio2010]特别行动队
    bzoj 1096: [ZJOI2007]仓库建设
    bzoj 3522: [Poi2014]Hotel
    bzoj 3572: [Hnoi2014]世界树
    bzoj 1177: [Apio2009]Oil
    bzoj 1912: [Apio2010]patrol 巡逻
    bzoj 3573: [Hnoi2014]米特运输
    bzoj 3997: [TJOI2015]组合数学
    cf 506 A. Mr. Kitayuta, the Treasure Hunter
    cf 500 D. New Year Santa Network
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/12931480.html
Copyright © 2020-2023  润新知