当前位置:
文档之家› 《计算机考研复试上机指导全书习题集》试读版
《计算机考研复试上机指导全书习题集》试读版
《计算机考研复试上机指导全书习题集》试读版
1001. A+B Format (20)
Time Limit: 400 MS Memory Limit: 65536 KB
题意
给出两个整数 a、b(不超过 10^9),求 a+b 的值,并按照 xxx,xxx,xxx,xxx 的格式输出。
样例解释
Sample One -1000000 + 9 = -999991 按照格式输出为-999,991。
Note 2: 当一个客户服务结束时,下一个客户的服务将立即开始,剩余客户也立即入队,中间无缝 对接,不产生额外时间。
Note 3: 关于时间的处理有一个小小的技巧,就是把时间都转换为分钟,即把 hh:mm 形式的时间全 部转换为分钟数 hh*60+mm,以便于时间的处理和比较。
= 38 =
参考代码
W.popTime += needTime[W.q.front()];
//更新该窗口的 popTime
ans[inIndex] = W.endTime; //客户 inIndex 的服务结束时间为该窗口的 endTime
}
for(int i = 0; i < query; i++) {
scanf("%d", &q);
//循环入队
window[inIndex % n].q.push(inIndex);
//更新窗口的服务结束时间 endTime
window[inIndex % n].endTime += needTime[inIndex];
//对窗口的第一个客户,更新 popTime
if(inIndex < n) window[inIndex].popTime = needTime[inIndex];
printf("-"); sum = -sum; } int len = 0; //len 存放 sum 的长度 if(sum == 0) num[len++] = 0; //sum 为 0 时特殊处理 while(sum) { //将 sum 存入数组 num[]中,其中 sum 的低位存放到 num[]的低位 num[len++] = sum % 10; //将 sum 的末位 sum%10 存放到 num[len],然后 len++ sum /= 10; //去除 sum 的末位 } for(int k = len - 1; k >= 0; k--) { //从高位开始输出 printf("%d", num[k]); if(k > 0 && k % 3 == 0) printf(","); //每三位一个逗号,最后一位除外 } return 0; }
//服务结束时间、服务需要时间
int main() {
int inIndex = 0;
//当前第一个未入队的客户编号
scanf("%d%d%d%d", &n, &m, &k, &query); //窗口数、窗口人数上限、客户数、查询数
for(int i = 0; i < k; i++) {
scanf("%d", &needTime[i]); //读入服务需要时间
//当前入队的客户的服务结束时间直接保存作为答案
ans[inIndex] = window[inIndex % n].endTime;
inIndex++;
}
for(; inIndex < k; inIndex++) {
//处理剩余客户的入队
int idx = -1, minPopTime = 1 << 30;
参考代码
#include <cstdio> int num[10]; int main() {
int a, b, sum; scanf("%d%d",&a, &b); sum = a + b; //将 a+b 赋值给 sum if(sum < 0) { //sum 为负数时,输出负号并取 sum 的相反数
考察点
字符串处理
思路
Step 1 对输入的两个数字 a 与 b 进行累加,并赋值给 sum。之后判断累加后得到的 sum 是否为负数,
如果是负数,则负号先行输出,并令 sum = -sum 来取正。 Step2
把 sum 的每一位存到数组中(例如 123 存到数组 num[]中就是 num[0] = 3、num[1] = 2、num[2] = 1,即 sum 的低位存储到 num[]的低位),之后从高位开始输出数组元素,每输出 3 个数字输出 1 个逗号,最后 3 个数字后面不输出。
= 37 =
考察点
排队问题
思路
Step 1 考虑一个事实:当一位客户进入某一窗口的队列时,他的服务结束时间就已经确定了,即当前
在该窗口排队的所有人的服务时间之和。而在所有窗口排满后,剩余客户能够去排队的时间点是所 有窗口最早结束的队首客户,也就是说,在所有窗口排满的情况下,每当有一个窗口的队首客户服 务结束(结束时间相同的,窗口 ID 小的视为先结束),剩余客户的第一个就会排到那个窗口最后面 去。于是我们可以为窗口建立一个结构体 Window,存放该窗口当前队伍的最后服务时间 endTime 和队首客户的服务结束时间 popTime,并维护一个该窗口的排队队列 q,如下所示:
//寻找所有窗口的最小 popTime
for(int i = 0; i < n; i++) {
if(window[i].popTime < minPopTime) {
idx = i;
minPopTime = window[i].popTime;
}
}
= 39 =
//找到最小 popTime 的窗口编号为 idx,下面更新该窗口的队列情况
Window& W = window[idx]; //引用,下文中用 W 代替 window[idx],行文更清晰
W.q.pop();
//队首客户离开
W.q.push(inIndex); //客户 inIndex 入队
W.endTime += needTime[inIndex];
//更新该窗口队列的 endTime
=6=
1014. Waiting in Line (30)
Time Limit: 400 MS Memory Limit: 65536 KB
题意
某银行有 N 个窗口,每个窗口前最多可以排 M 个人。现在有 K 位客户需要服务,每位客户的 服务时长已知。假设所有客户均在 08:00 时刻按客户编号次序等在黄线外,且如果有窗口的排队人 数没有排满(没有达到 M 人),当前在黄线外的第一个客户就会选择这样的窗口中排队人数最少的 窗口去排队(排队人数相同时,选择窗口序号最小的窗口去排队)。给出 Q 个查询,每个查询给出 一位客户的编号,输出这位客户的服务结束时间。注意,如果一个客户在 17:00 之后(含 17:00)还 没有被服务,则不再服务,输出 Sorry;而如果一个客户在 17:00 之前被服务,那么无论他的服务时 长有多长,都会服务完整。
num[len] = sum % 10; sum /= 10; ++len; } //使用 do...while 的写法
=5=
int len = 0; do {
num[len] = sum % 10; sum /= 10; ++len; }while(sum);
Note 2: 注意最低位后面是不需要输出逗号的,所以需要在输出逗号时判断是否是最低位。
return h * 60 + m; //转换时间为分钟,方便时间处理
}
struct Window {
int endTime, popTime; //窗口当前队伍的最后服务时间、队首客户的服务结束时间
queue<int> q; //队列
} window[20];
int ans[maxNode], needTime[maxNode];
}
for(int i = 0; i < n; i++) { //初始化每个窗口的 popTime 和 endTime 为 08:00
window[i].popTime = window[i].endTime = convertToMinute(8, 0);
}
for(int i = 0; i < min(n * m, k); i++) { //注意是 min(n*m, k)
样例解释
Sample One 有两个窗口,每个窗口前最多排两个人,初始状态下 7 个客户都在黄线外,然后按照选择窗口
的规则进行排队,得到如图的排队情况,其中每个客户右下角的中括号中的数字表示该客户当前剩 余的服务时间。
由于 1 号客户的剩余服务时间比 2 号客户更短,因此 1 号客户在 08:01 时先行服务完毕,5 号 客户排到 1 号窗口后面,同时 2 号客户的剩余服务时间减少 1 分钟,得到下图 08:01 的状态图。接 下来的步骤过程与此类似,这里不再赘述,读者可以从图中得到整个过程,其中在 17:00 时 7 号客 户将无法被服务,因此 7 号客户应当输出 Sorry。
#include <cstdio>
#include <queue>
#include <algorithm>