ccf160902-火车购票
题目
问题描述
假设一节车厢有20排、每一排5个座位。为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排是6到10号,依次类推,第20排是96到100号。
购票时,一个人可能购一张或多张票,最多不超过5张。如果这几张票可以安排在同一排编号相邻的座位,则应该安排在编号最小的相邻座位。否则应该安排在编号最小的几个空座位中(不考虑是否相邻)。
假设初始时车票全部未被购买,现在给了一些购票指令,请你处理这些指令。
第二行包含n个整数,每个整数p在1到5之间,表示要购入的票数,相邻的两个数之间使用一个空格分隔。
对于购票指令p,输出p张车票的编号,按从小到大排序。
2 5 4 2
6 7 8 9 10
11 12 13 14
3 4
2) 购5张票,得到座位6至10。
3) 购4张票,得到座位11至14。
4) 购2张票,得到座位3、4。
思路
我的思路特别直白而且傻。。。有很多可以用循环合在一起的部分,但是这样提交也是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; }