CCF201609-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。
 
解题思路:首先是要分两种情况来讨论:第一种是还存在某一行的座位数量够分配给购票的人,一种是当前行不够分,需要继续查找下一行。
第一种情况的话就很简单,只需要查找剩余的座位大于购票人的需求的行,计算出开始位置结束位置就可以输出座位号了。
第二种情况就是每一行都不够当前购票者的需求,那么就需要多行来分配了,首先从最开始的行来寻找,有空座位就把空座位分配,如果给购票者的座位分配够了就结束循环,不够的话继续查找下一行。
 
我是用到一个长度为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;
}
唯有热爱方能抵御岁月漫长。
原文地址:https://www.cnblogs.com/syq816/p/12423219.html