ccf160902-火车购票

题目

问题描述

  请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配。
  假设一节车厢有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。

思路

我的思路特别直白而且傻。。。有很多可以用循环合在一起的部分,但是这样提交也是100分,就懒得优化算法了。

本来第一次提交是90分,确实是有边界情况没有考虑到。如果没有连坐的时候,分开坐的那部分代码写得有点问题,而且忘记给已经卖完票的位置置0.&定义了一个num用来记录每次卖票已经卖了几张,由于开始是放在for循环外面定义的,没有及时将它归零。

因为一共只有五种购票情况,所以我对于五种情况都分别进行考虑。

构建了一个二维数组,数组的元素值是这个位置对应的座位号,如果这个座位已经被卖出了,那么就置0。

比如购买三张票:

1)首先考虑能买连坐的情况。重点在于怎么确定当前的几个位置是在同一排,我本来是想多定义一个int preLine,用于记录上一个位置是在哪一行,如果上一个位置行数和这一个位置的行不一样,那么就说明跨行了。但这样就会出现,因为跨行了每行第一列的元素已经做了判断,由于不符合条件没有进入这个循环,无法记录到跨完行的下一行第一列的位置。就会直接进入到下一行第二列元素的判断。。。

那么我又想,既然第一个列的元素进不了,那我在设置if条件的时候,就多加一条把第一列的元素作为条件放进来。但是这样就造成了依旧可能不跨行,因为上一行的最后一个元素也符合条件一加进来了,下一行的第一个元素也符合条件二加进来了,那么他们就会集合下一行第二个元素凑成三个座位进行输出了。

所以直接简单粗暴地给出既然是买同一排的三张票,显然不能处于第四、第五列(如第一排买123 234 345,再往下就要跨行了)。把这两个位置去除了,就直接解决了怎么确定当前位置是同一排了,因为不会存在跨行情况了。

2)如果上一个循环没有输出结果(即没有连坐票),再考虑不能买连坐的情况,这种情况对于购买几张票都是一样的操作,就是循环所有的票,取座位号最小的N张。

题解

 

#include<iostream>
using namespace std;

int main(){
    int seats[20][5];
    for(int i=0;i<20;i++){
        for(int j=0;j<5;j++){
            seats[i][j]=i*5+j+1;
        }
    }
    int n;
    scanf("%d",&n);
    int buys[n];
    for(int i=1;i<n+1;i++){
        scanf("%d",&buys[i]);
    }
    for(int i=1;i<n+1;i++){
        int labelBreak=0;
        int label=0;
        int num=0;
        int preLine=0;//前一个值是哪一行 
        if(buys[i]==1){//直接买最小的 
            for(int p=0;p<20;p++){
                for(int q=0;q<5;q++){
                    if(seats[p][q]!=0){
                        printf("%d\n",seats[p][q]);
                        seats[p][q]=0;
                        labelBreak=1;
                        break;
                    }
                }
                if(labelBreak==1){
                    labelBreak=0;
                    break;
                }
            }
        }
        else if(buys[i]==5){//五张票
            for(int p=0;p<20;p++){//先判断是否能买连坐
                if(seats[p][0]!=0 && seats[p][1]!=0 && seats[p][2]!=0 && seats[p][3]!=0 && seats[p][4]!=0){
                    printf("%d %d %d %d %d\n",seats[p][0],seats[p][1],seats[p][2],seats[p][3],seats[p][4]);
                    seats[p][0]=0;
                    seats[p][1]=0;
                    seats[p][2]=0;
                    seats[p][3]=0;
                    seats[p][4]=0;
                    label=1;
                    break;        
                }
            } 
            if(label==0){//没有连坐,选编号最小的5个位置
                for(int p=0;p<20;p++){
                    for(int q=0;q<5;q++){    
                        if(seats[p][q]!=0){
                            num++;
                            if(num==5){ 
                                printf("%d\n",seats[p][q]);    
                                seats[p][q]=0;
                                labelBreak=1;
                                break;                                    
                            }
                            printf("%d ",seats[p][q]);
                            seats[p][q]=0;
                            //labelBreak=1;
                            //break;                            
                        }
                    }
                    if(labelBreak==1){
                        labelBreak=0;
                        break;
                    }
                } 
            }    
        }
        else if(buys[i]==4){//四张票
            for(int p=0;p<20;p++){//先判断是否能买连坐
                for(int q=0;q<5;q++){
                    if(seats[p][q]!=0){
                        num++;
                        if((num==1 && q==2) || (num==1 && q==3) || (num==1 && q==4)){
                            num=0;
                            break;
                        }
                        if(num==4){
                            printf("%d %d %d %d\n",seats[p][q-3],seats[p][q-2],seats[p][q-1],seats[p][q]);
                            seats[p][q-3]=0;
                            seats[p][q-2]=0;
                            seats[p][q-1]=0;
                            seats[p][q]=0;
                            labelBreak=1;    
                            label=1;
                        }
                    }
                    //else if(seats[p][q]==0){
                    else{
                        num=0;
                    }
                    if(labelBreak==1){
                        break;
                    }
                }
                if(labelBreak==1){
                    labelBreak=0;
                    break;
                }
            } 
            if(label==0){//没有连坐,选编号最小的4个位置
                for(int p=0;p<20;p++){
                    for(int q=0;q<5;q++){    
                        if(seats[p][q]!=0){
                            num++;
                            if(num==4){ 
                                printf("%d\n",seats[p][q]);    
                                seats[p][q]=0;
                                labelBreak=1;
                                break;                                    
                            }
                            printf("%d ",seats[p][q]);
                            seats[p][q]=0;
                            //labelBreak=1;
                            //break;                            
                        }
                    }
                    if(labelBreak==1){
                        labelBreak=0;
                        break;
                    }
                } 
            }    
        }        
        else if(buys[i]==3){//3张票
            for(int p=0;p<20;p++){//先判断是否能买连坐
                for(int q=0;q<5;q++){
                    if(seats[p][q]!=0){
                        num++;
                        if((num==1 && q==3) || (num==1 && q==4)){
                            num=0;
                            break;
                        }
                        if(num==3){
                            printf("%d %d %d\n",seats[p][q-2],seats[p][q-1],seats[p][q]);
                            seats[p][q-2]=0;
                            seats[p][q-1]=0;
                            seats[p][q]=0;
                            labelBreak=1;    
                            label=1;
                        }
                    }
                    else if(seats[p][q]==0){
                        num=0;
                    }
                    if(labelBreak==1){
                        break;
                    }
                }
                if(labelBreak==1){
                    labelBreak=0;
                    break;
                }
            } 
            if(label==0){//没有连坐,选编号最小的3个位置
                for(int p=0;p<20;p++){
                    for(int q=0;q<5;q++){    
                        if(seats[p][q]!=0){
                            num++;
                            if(num==5){ 
                                printf("%d\n",seats[p][q]);    
                                seats[p][q]=0;
                                labelBreak=1;
                                break;                                    
                            }
                            printf("%d ",seats[p][q]);
                            seats[p][q]=0;
                            //labelBreak=1;
                            //break;                            
                        }
                    }
                    if(labelBreak==1){
                        labelBreak=0;
                        break;
                    }
                } 
            }    
        }
        else if(buys[i]==2){//2张票
            for(int p=0;p<20;p++){//先判断是否能买连坐
                for(int q=0;q<5;q++){
                    if(seats[p][q]!=0){
                        num++;
                        if(num==1 && q==4){
                            num=0;
                            break;
                        }
                        if(num==2){
                            printf("%d %d\n",seats[p][q-1],seats[p][q]);
                            seats[p][q-1]=0;
                            seats[p][q]=0;
                            labelBreak=1;    
                            label=1;
                        }
                    }
                    else if(seats[p][q]==0){
                        num=0;
                    }
                    if(labelBreak==1){
                        break;
                    }
                }
                if(labelBreak==1){
                    labelBreak=0;
                    break;
                }
            } 
            if(label==0){//没有连坐,选编号最小的2个位置
                for(int p=0;p<20;p++){
                    for(int q=0;q<5;q++){    
                        if(seats[p][q]!=0){
                            num++;
                            if(num==2){ 
                                printf("%d\n",seats[p][q]);    
                                seats[p][q]=0;
                                labelBreak=1;
                                break;                                    
                            }
                            printf("%d ",seats[p][q]);
                            seats[p][q]=0;
                            //labelBreak=1;
                            //break;                            
                        }
                    }
                    if(labelBreak==1){
                        labelBreak=0;
                        break;
                    }
                } 
            }    
        }        
        
    }
    return 0;
}

 

 

 

 

 

posted @ 2019-09-08 23:31  闲不住的小李  阅读(442)  评论(0编辑  收藏  举报