已知公交车中有n排座位,每排都有2个座位。第i排的两个座位的宽度均为wi厘米。没有相同宽度的两排座位。
公共汽车最初是空的。有2n位乘客按顺序先后进入公共汽车。 乘客分为两种类型:
内向者:总是选择两个座位都没人的一排。在这些排中,他选择座位宽度最小的,并占据了其中的一个座位; 外向型:总是选择有人的一排。 在这些排中,他选择座位宽度最大的那个,并占据了空位。
你会得到每排座位的宽度和乘客进入公共汽车的顺序。 请你帮忙确定每位乘客将乘坐哪一排座位。
输入格式:
第一行包含一个整数n(1 ≤ n ≤ 200),表示公共汽车上座位的总排数。
第二行是一个包含n个整数的序列w 1,w 2,...,w n(1 ≤ w i ≤ 10000),其中wi是第i行中每个座位的宽度。 保证所有 w i 都不同。
第三行包含一个长度为 2n 的字符串,由数字“0”和“1”组成,该字符串描述了乘客进入公共汽车的顺序。 如果第j个字符是 '0',那么说明第 j 个进入公共汽车的乘客是内向型的;如果第j个字符是 '1',则表示第j个进入公交车的乘客是外向型的。 保证外向者的数量等于内向者的数量(即'0'和'1'的个数均为 n),并且对于每个外向者总是有合适的行。
输出格式:
打印 2n 个整数,整数之间以空格分隔,表示乘客将坐的排。 乘客的顺序应与输入的顺序相同。
输入样例1:
2
3 1
0011
输出样例1:
2 1 1 2
输入样例2:
6
10 8 9 11 13 5
010010011101
输出样例2:
6 6 2 3 3 1 4 4 1 2 5 5
代码 :
#include<stdio.h>
int main()
{
int row_of_seat; scanf("%d", &row_of_seat);
int seat[row_of_seat+1], num_of_human = row_of_seat * 2;
int stack[num_of_human + 1], top = 0; // 建立栈
for (int i = 0; i < row_of_seat; i ++) // 输入座位宽度
{
scanf("%d", &seat[i]);
}
char human[num_of_human + 1]; scanf("%s", human); // 人性格类型
for (int i = 0; i < num_of_human; i++)
{
// 如果本次循环到1(外向),输出栈顶并退栈.
if (human[i] == '1') {printf("%d ", stack[--top]);}
// 否则就是内向的人,我们就遍历剩下空的座位找到最小宽度的然后入栈.
else
{
int min = 114514, minj = 0; // 好恶臭的min
for (int j = 0; j < row_of_seat; j++)
{
if (seat[j] < min && seat[j] != -1)
{
min = seat[j];
minj = j;
}
}
printf("%d ", minj + 1); // 找到了以后先输出这个人坐的位置.
stack[top++] = minj + 1;
seat[minj] = -1; // 这里把有人的座位宽度改成-1来标志已经有人坐了.
}
}
return 0;
}
总结:
这道题分析清楚后其实就是一道关于栈的题目。
我们注意到内向的人只会坐在没人坐的位置,而外向的人只会坐在有人的位置,因此每一排都是内向的人和外向的人匹配,不会出现两个内向、外向的人坐在一起的情况。并且内向的人总是挑最窄的坐,外向的人总是挑最宽的坐。
因此,我们建立一个栈,每次遇到内向的人就找当前无人的最小的位置入栈,就能保证栈顶的座位宽度是栈内最大。遇到外向的人就输出栈顶并退栈(栈内的位子都是有一个内向的人坐并且宽度最大)就行了。