目录
一、问题描述
问题描述
请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配。
假设一节车厢有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;
}
三、总结
虽然最后靠自己做出来了,但也是调试了好多遍,花了不少时间。归根结底还是:一定要保持思路清晰,不能老是犯低级错误和不该犯的错误!!!