CSP-CCF★201609-2火车购票★

目录

一、问题描述

二、解答

三、总结


一、问题描述

问题描述

  请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配。
  假设一节车厢有20排、每一排5个座位。为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排是6到10号,依次类推,第20排是96到100号。
  购票时,一个人可能购一张或多张票,最多不超过5张。如果这几张票可以安排在同一排编号相邻的座位,则应该安排在编号最小的相邻座位。否则应该安排在编号最小的几个空座位中(不考虑是否相邻)。
  假设初始时车票全部未被购买,现在给了一些购票指令,请你处理这些指令。

输入格式

  输入的第一行包含一个整数n,表示购票指令的数量。
  第二行包含n个整数,每个整数p在1到5之间,表示要购入的票数,相邻的两个数之间使用一个空格分隔。

输出格式

  输出n行,每行对应一条指令的处理结果。
  对于购票指令p,输出p张车票的编号,按从小到大排序。

样例输入

4
2 5 4 2

样例输出

1 2
6 7 8 9 10
11 12 13 14
3 4

样例说明

  1) 购2张票,得到座位1、2。
  2) 购5张票,得到座位6至10。
  3) 购4张票,得到座位11至14。
  4) 购2张票,得到座位3、4。

评测用例规模与约定

  对于所有评测用例,1 ≤ n ≤ 100,所有购票数量之和不超过100。

二、解答

思路:创建1个seat的结构体,有两个元素:no来记录序号,state来记录是否被坐(false表示空位),剩下的详见代码注释

代码:

#include<iostream>
using namespace std;
struct Seat {//创建seat结构体
	int no;//记录座位序号
	bool state;//记录座位状态,false表示空位,true表示已被坐
}seat[20][5];//实例化成二维数组,方便表示位置,注意这里最好就是20*5,如果想从1开始、定为21*6,那么会有第0排、第0列没有赋值而引起不必要的麻烦
int main()
{
	int n;
	cin >> n;
	int p[101] = { 0 };
	for (int i = 0; i < n; i++)
	{
		cin >> p[i];//购票指令用一个一维数组存储
	}
	int m = 1;
	for (int i = 0; i < 20; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			//对seat的2个元素分别赋值、初始化
			seat[i][j].state = false;//false表示空位
			seat[i][j].no = m;
			m++;
		}
	}
	for (int k = 0; k < n; k++)
	{
		//两种情况
		//情况1:可以被安排在同一排
		int count = 0;
		for (int i = 0; i < 20; i++)//检测每一排是否有满足条件的
		{
			int num = 0;
			int col = 0;
			for (int j = 0; j < 5; j++)
			{
				//注意:if语句是双等号!!!
				if (seat[i][j].state == false)//这里不必考虑突然中间出现一个true,因为根据题目可以知道,一旦当前是空位,那么同一排的后几列也都是空位
				{ if(num == 0)
				{
					num++;
					col = j;//记录第一次出现空位的列数
				}
				else {
					num++;
				}
				}
				if (num == p[k])//检测到可以坐同一排
				{
					int row = i;
					for (int j = col; j < col + p[k]; j++)//注意:这里的j不是从1开始的!!!
					{
						seat[row][j].state = true;
						cout << seat[row][j].no << " ";
					}
					cout << endl;
					break;
				}
			}
			if (num == p[k]) 
			{ break; }
			 count++;  //注意:这里else可加可不加
		}
		//情况2:不能被安排在同一排,即:将所有排都遍历了1遍还是没有符合条件的
		//这时:应该安排在编号最小的几个空座位中(!!不考虑是否相邻!!)
		if (count == 20)
		{
			int count2 = 0;
			for (int i = 0; i < 20; i++)
			{
				for (int j = 0; j < 5; j++)
				{
					if (seat[i][j].state == false)
					{
							cout << seat[i][j].no << " ";
							seat[i][j].state = true;
							count2++;
					}
					if (count2 == p[k])
					{
                            cout << endl;
							break;
					}
				}
					if (count2 == p[k])
					{
						break;
					}
			}
		}
		
	}
	return 0;
}

三、总结

虽然最后靠自己做出来了,但也是调试了好多遍,花了不少时间。归根结底还是:一定要保持思路清晰,不能老是犯低级错误和不该犯的错误!!!

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值