题目描述:
设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。
输入格式:
输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。
输出格式:
按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。
1、算法描述
(1)首先需要设置两个队列A和B。所有元素入队。奇数入A ,偶数入B。 ——> 一个for循环,一组if
(2)出队操作。当某个队列变成空时,输出另一个队列的非空部分。——> while
while (na <= ia && nb <= ib) | 这时,一个队列为空时就会退出循环,之后判断到底是哪个队列为空了( na == ia) 还是 (nb == ib),然后分情况操作。如果na == ia, 则从nb 开始输出直到nb == ib。 在while循环中,我们的操作是:两次a的输出(用for)和一次b的输出,没有额外的判定条件 |
while (na <= ia || nb <= ib) | 我们不妨换个思路。反正最后也都是要把两个队列的所有元素输出的,不如设为只要还有一个队列不空,就继续执行操作。区别于第一种方法的是,当有一个队列为空时,不能再进行输出操作了,应当直接跳过对应队列的操作。所以比上一种方法多的是一个判断空队列语句: if (na <= ia) output a[na]; if (nb <= ib) output b[nb]; 如果队列为空了,而na,nb的起始值都是1,空队列对应的输出语句就会跳过不执行,达到输出非空队列剩余元素的目的 |
2、重点关注
入队时序号自增的微妙操作 | 也就是说,在这里我希望变量ia和xa都能直观地表示数组元素个数,而并不会用到其索引含义。 |
中间有空格但是末尾不能有空格的处理 | 在每个字符前面加空格,设置一个标记变量flag,用于标记是不是第一个字符。如果是第一个输出的字符,就不要在他的前面输出空格 |
大循环中包含一个两重循环和一个一重循环 | for (j = 0; j < 2; j++) { if ( na <= ia) cout; } |
为什么这个里面不能先判断na <= ia 再执行循环操作呢? 我们知道这个na <= ia是为了判断a队列是否为空的。每一次a输出一个值我们就需要考虑他是否为空,以免a中有奇数个元素。如果先判断再输出,相当于一次性一定捆绑输出两个。这在元素是奇数个时是会出错的。 | |
i和j | 在本题中i和j都是标记循环次数的变量,没有索引的含义 |
3、代码
#include <stdio.h>
int main()
{
int a[1005], b[1005];
int n;
scanf("%d",&n);
int i;
int index;//编号
int ia = 0,ib = 0;
for (i = 1; i <= n; i++) {
scanf("%d", &index);
if (index % 2 == 1) {
//奇数编号,去A窗口
a[++ia] = index;//为了编号好处理,不给0存入数据,B也同理
}
else {
//偶数编号,去B窗口
b[++ib] = index;
}
}
//输出
int na=1,nb=1;//标记现在输出到了哪里
int j;
int flag = 0;//用于处理空格.当flag为0时,还没有元素输出,也就是说此时是要第一个元素输出,这个元素之前不需要有空格。当这个元素输出之后,flag++,后面的所有元素都需要在前面加一个空格。flag就会作为判断的条件
//结束:任意队列为空,输出另一个非空队列。这里处理为:只要还有一个元素没有输出,就继续输出,那么线面就需要判断到底是哪个还没有输出完毕
while ( na <= ia || nb <= ib) {
//体现a和b的处理速度,输出两个a中的元素才能输出一个b中的元素
//这里主要是进行空格的处理
//如果a先空且b不空,则b在最后一个元素输出是不能有空格。
//如果b先空且a不空,则a在最后一个元素输出时不能有空格
//如果ab同时为空,则b在最后一个元素输出时不能有空格不要
//由此可知,如果把空格放在元素输出之后再输出,就会变得比较复杂,所以可以把他放在元素输出之前输出,我们只需要保证第一个元素输出之前不要输出空格即可
//循环输出两个a
for (j = 0; j < 2; j++) {
if (na <= ia) {
if (flag) {
printf(" ");
}
flag++;
printf("%d",a[na]);
na++;
}
}
//输出b
if (nb <= ib) {
if (flag) {
printf(" ");
}
flag++;
printf("%d",b[nb]);
nb++;
}
}
return 0;
}