CCF认证 - 201609-2 - 火车购票 C语言代码实现(100分)

之前在考虑问题时忽略了类似于这种情况:
假如有21人购票,每个人买四张票,那么之前的90分代码会导致第21人无法购买成功,
这是因为for(h = 0; h < 20; h++)该层循环在h到达20后不再继续,事实上第21人的四张票仍
然能够以散座的形式出售,所以导致代码错误。
在for(int i = 0; i < n; i++)与for(h = 0; h < 20; h++)两个循环之间加入下列代码段:

		if(tag == 0 && h == 20)// (容易忽略的地方!!!)此时遍历数组未能找到能坐下的行,则应分散座位;
				 for(int hang = 0; hang < 20; hang++)
				 {
					for(int lie = 0; lie < 5; lie++)
					 	{
						 	if(seat[hang][lie] == 0)
							 	{
							 		seat[hang][lie] = 1;
							 		printf("%d ", zuohao[hang][lie]);
							 		num--;
								 } 
							if(num == 0)
								break;
						}
					if(num == 0)
						{
							printf("\n");
							break;
						}
				} 

对超过20人的情况进行讨论,之后便可以完成散座的出售。

#include<stdio.h>
int main() {
	int n, a[100] = {0}, seat[20][5] = {0}, num, ls = 5, flag = 0, tag = 0;//数组seat表示座位的占用情况;
	scanf("%d", &n);
	int h;
	for(int i = 0; i < n; i++)
		scanf("%d", &a[i]);

	int zuohao[20][5], count = 1;
	for(int i = 0; i < 20; i++)
		for(int j = 0; j < 5; j++)
			zuohao[i][j] = count++;//数组zuohao记录座号;

	for(int i = 0; i < n; i++) {
		num = a[i];//num记录当前购票数;
		tag = 0;
		for(h = 0; h < 20; h++) {
			for(int l = 0; l < 5; l++) {
				if(seat[h][l] == 1) {
					ls--;
					//continue;    //解释因为加continue而引起的错误:
					//加入continue的本意是跳过当前行中
					//已被占用的座位,但导致了:当一行中
					//所有的位置被占满时,第17行的for循环
					//直接结束,从而导致ls = 5无法执行,即
					//ls无法进行初始化,导致下一次第15行for
					//循环执行时,ls的值不为5,所以执行到第
					//41行跳出,即少进行了一次for循环,从而
					//导致了座位会空出一行。
					//若不加continue,则可以达到正确结果,
					//不过执行的代码也相应增多;
				}//若座位被占,则当前行的剩余座位数减一;
				if(ls < num) {
					ls = 5;
					break;
				}//若剩余座位数不足,则直接跳到下一行;
				if(seat[h][l] == 0 && ls >= num) {
					for(int k = l; k < l + num; k++)
						if(seat[h][k] == 1) {
							flag = 1;
							break;
						}
					if(flag == 0) {
						for(int j = l; j < l + num; j++) {
							seat[h][j] = 1;
							printf("%d ", zuohao[h][j]);
							tag = 1;
						}//分配座位;
						printf("\n");
						ls = 5;
					}

				}
				flag = 0;
				if(tag == 1)
					break;//tag为1说明当前座位分配完成,可以进行下一个分配;
			}
			if(tag == 1)
				break;//tag为1说明当前座位分配完成,可以进行下一个分配;
			
		}
		if(tag == 0 && h == 20)// (容易忽略的地方!!!)此时遍历数组未能找到能坐下的行,则应分散座位;
				 for(int hang = 0; hang < 20; hang++)
				 {
					for(int lie = 0; lie < 5; lie++)
					 	{
						 	if(seat[hang][lie] == 0)
							 	{
							 		seat[hang][lie] = 1;
							 		printf("%d ", zuohao[hang][lie]);
							 		num--;
								 } 
							if(num == 0)
								break;
						}
					if(num == 0)
						{
							printf("\n");
							break;
						}
				} 
	}
		/*for(int i = 0; i < 5; i++)
		{
			for(int j = 0; j < 5; j++)
				printf("%d ", seat[i][j]);
			printf("\n");
		}*/ 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值