1.题目描述:
在一辆公交车中有n排座位,每一排有两个座位。第 i排的两个座位的宽度均为 wi 。所有的 wi 互不相同。
初始时,公交车是空的。接下来会依次停靠 2n 个站,每一站将上来一名乘客。乘客分为两类:
- 内向者:此类乘客总是会选择两个座位都是空的那一排就坐,如果有多排都是空的,他将会选择 wi 最小的那一排中任意一个空座坐下。
- 外向者:此类乘客总是会选择已有一人就坐(当然是内向者)的那一排,如果有多排都满足条件,他会选择 wi 最大的那一排的空座坐下。
现在给定每一排的宽度 wi 以及乘客上车的顺序。请确定每一个乘客将会选择哪一排坐下。
2.涉及的知识点:stack
下进上出。长度始终不变。
例子:
stack<int> q;
q.push(x);
q.top();
q.pop();
q.size();
q.empty;
3.该题思路:
用一个结构体存下每排的序号和对应的宽度,并建立一个结构体数组,并为其中排结构体的序号和宽度赋值。
并建立一个用于结构体的栈。
并建立一个包含上车人数组x[i],里面的元素要么是'0',要么是'1'。
注意:
(1)内向的人最好是第一个上车的,这样让之后上来的如果是一个外向的人,那他能面临一个最好的情况,就是和内向的人一起坐。
(2)事先把包含所有排情况的结构体数组按宽度由小到大的顺序排列好,便于内向的人选择宽度最小的排。
(3)结构体数组是服务于内向的人的,stack栈是服务于外向的人的,内向的人从结构体数组中拿出排坐,坐了的排又进栈,外向的人从栈里面拿一个排出来和内向的人一起坐。
(4)一种特殊情况:第一个人是内向的,第二个人如果外向,第三个人一定内向
4.大致的过程描述
(1)一个内向的人上来了,这个时候座位都是空的,那就坐宽度最小的,也就是结构体数组的第一个结构体,然后把这个结构体放在栈的最下面,并输出这个结构体的排的序号
(2) 如果接下来上来的还是内向的人,那不能坐之前那个内向的人的排了,就坐宽度第二小的,也把宽度对应的结构体放在栈里,并输出这个结构体排的序号,同时也把结构体数组指针往后移一位,下次如果还是内向的人就没法坐这一排。
如果接下来是外向的人,那外向的人就会和第一个内向的人坐同一排,就从栈中拿一个排出来坐,并输出这个排的序号,又把这个排移出栈。表示这排已经坐满了,下一个外向的人坐不了了。
(3)接着如果上来的是内向的人,就又把结构体指针对应的第二小或者第三小宽度结构体放进栈里,并输出这个结构体对应的排序号。
(4)然后如果上来的又是外向的人,就找个内向的人坐一排,并把对应的结构体移出栈表示这排坐满了。
(5)依次类推
4.代码:
#include <bits/stdc++.h>
using namespace std;
struct pai{
int hao;
int kuan;
}a[200005];
bool cmp(pai a,pai b){
return(a.kuan<b.kuan);
}
char ren[400010];
int main()
{
int n;
cin>>n;
int i;
for(i=1;i<=n;i++){
cin>>a[i].kuan;
a[i].hao=i;
}
int j;
for(j=1;j<=2*n;j++){
cin>>ren[j];
}
stack<pai> linshi;
j=1;//排号
struct pai t;
sort(a+1,a+n+1,cmp);
for(i=1;i<=n*2;i++){//人上车了
if(ren[i]=='0'){
linshi.push(a[j]);
cout<<a[j].hao<<' ';
j++;
}else{
t=linshi.top();
cout<<t.hao<<' ';
linshi.pop();
}
}
return 0;
}