问题描述
请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配。
假设一节车厢有20排、每一排5个座位。为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排是6到10号,依次类推,第20排是96到100号。
购票时,一个人可能购一张或多张票,最多不超过5张。如果这几张票可以安排在同一排编号相邻的座位,则应该安排在编号最小的相邻座位。否则应该安排在编号最小的几个空座位中(不考虑是否相邻)。
假设初始时车票全部未被购买,现在给了一些购票指令,请你处理这些指令。
假设一节车厢有20排、每一排5个座位。为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排是6到10号,依次类推,第20排是96到100号。
购票时,一个人可能购一张或多张票,最多不超过5张。如果这几张票可以安排在同一排编号相邻的座位,则应该安排在编号最小的相邻座位。否则应该安排在编号最小的几个空座位中(不考虑是否相邻)。
假设初始时车票全部未被购买,现在给了一些购票指令,请你处理这些指令。
输入格式
输入的第一行包含一个整数n,表示购票指令的数量。
第二行包含n个整数,每个整数p在1到5之间,表示要购入的票数,相邻的两个数之间使用一个空格分隔。
第二行包含n个整数,每个整数p在1到5之间,表示要购入的票数,相邻的两个数之间使用一个空格分隔。
输出格式
输出n行,每行对应一条指令的处理结果。
对于购票指令p,输出p张车票的编号,按从小到大排序。
对于购票指令p,输出p张车票的编号,按从小到大排序。
样例输入
4
2 5 4 2
2 5 4 2
样例输出
1 2
6 7 8 9 10
11 12 13 14
3 4
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。
2) 购5张票,得到座位6至10。
3) 购4张票,得到座位11至14。
4) 购2张票,得到座位3、4。
评测用例规模与约定
对于所有评测用例,1 ≤ n ≤ 100,所有购票数量之和不超过100。
解题思路:首先是要分两种情况来讨论:第一种是还存在某一行的座位数量够分配给购票的人,一种是当前行不够分,需要继续查找下一行。
第一种情况的话就很简单,只需要查找剩余的座位大于购票人的需求的行,计算出开始位置结束位置就可以输出座位号了。
第二种情况就是每一行都不够当前购票者的需求,那么就需要多行来分配了,首先从最开始的行来寻找,有空座位就把空座位分配,如果给购票者的座位分配够了就结束循环,不够的话继续查找下一行。
我是用到一个长度为20的数组来存储每排省多少座位的,大家可以自己选择顺手的容器来存储。
一个小测试技巧就是debug的时候可以把行数改小一点来测试第二种情况:
我的一个小测试案例,将行数改为3行,然后debug,可以看到哪块有问题。
4
3 5 4 3
#include<iostream> using namespace std; int a[20]; int main() { //初始化座位 for (int i = 0; i < 20; i++) a[i] = 5; int n; cin >> n; int num; int start, end;//售出座位的开始位置和结束位置 for (int i = 0; i < n; i++) { cin >> num; for (int j = 0; j < 20; j++) { if (a[j] >= num) { //当前行够分配 start = j * 5 + (5 - a[j] + 1); end = start + num - 1; //输出结果 for (int k = start; k <= end; k++) { if (k != start) cout << " "; cout << k; } cout << endl; a[j] -= num; num = 0;//已经全部分配完成 break; } } //一排不够分的情况 while (num > 0) { for (int j = 0; j < 20; j++) { if (a[j] >= num) { //当前行够分配 start = j * 5 + (5 - a[j] + 1); end = start + num - 1; //输出结果 for (int k = start; k <= end; k++) { if (k != start) cout << " "; cout << k; } cout << endl; a[j] -= num; num = 0;//已经全部分配完成 break; } else { //当前行不够分 //把当前行全部分配之后再继续查找下一行 if (a[j] > 0) { //当前行有剩余的座位,,当前行如果没有空着的座位的话则不能分配 start = j * 5 + (5 - a[j] + 1); end = start + a[j] - 1; for (int k = start; k <= end; k++) { cout << k<<" "; } } num -= a[j];//当前购票人还差几张票,如果全部分配完,那么num=0 } } } } system("pause"); return 0; }