问题 A: DS队列之银行排队
题目描述
在银行营业大厅共服务3种客户,类型为A\B\C,大厅分别设置了3个窗口分别服务三种客户,即每个窗口只服务一种客户。现有一批客户来银行办理业务,每个客户都有类型和办理业务时间。每个窗口按照客户到来的顺序进行服务。
编程实现它们的办理流程,请使用C++自带的queue必须使用队列实现,其他方法0分!
队列queue的用法如下:
1.包含头文件:#include
2.定义一个整数队列对象:queue myQe;
3.定义一个整数队列对象数组:queue myQA[10];
4.入队操作:myQe.push(itemp); //把整数itemp进入队列
5.出队操作:myQe.pop(); //把队头元素弹出队列,注意本操作不获取队头元素
6.获取队头元素: itemp = myQe.front(); // 把队头元素放入itemp中,注意本操作不弹出元素
7.判断队列是否为空:myQe.empty();//队列空则返回true,不空则返回false
输入
第一行输入先输入n表示客户数量
第二行输入每个客户的类型,数据之间用用空格隔开
第三行输入每个客户的办理时间,数据之间用用空格隔开
输出
第一行输出A类客户的平均办理时间
第二行输出B类客户的平均办理时间
第三行输出C类客户的平均办理时间
样例输入
8
A B C B C A A A
10 20 30 40 50 60 70 80
样例输出
55
30
40
AC代码
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
queue<char>q1;
queue<int>q2;
map<char, int>mapp;
map<char, int>num;
for (int i = 0; i < n; i++)
{
char temp;
cin >> temp;
num[temp]++;
q1.push(temp);
}
for (int i = 0; i < n; i++)
{
int temp;
cin >> temp;
q2.push(temp);
}
for (int i = 0; i < n; i++)
{
mapp[q1.front()] += q2.front();
q1.pop();
q2.pop();
}
cout << mapp['A'] / num['A'] << endl;
cout << mapp['B'] / num['B'] << endl;
cout << mapp['C'] / num['C'] << endl;
return 0;
}
问题 B: DS队列----银行简单模拟
题目描述
设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。
输入
输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。
输出
按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。
样例输入
8 2 1 3 9 4 11 13 15
样例输出
1 3 2 9 11 4 13 15
AC代码
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
queue<int>qa;
queue<int>qb;
queue<int>output;
vector<int>v;
for (int i = 0; i < n; i++)
{
int t;
cin >> t;
if (t % 2)
qa.push(t);
else
qb.push(t);
}
int cnt = 0;
while (!qa.empty())
{
output.push(qa.front());
qa.pop();
cnt++;
if (cnt == 2 && !qb.empty())
{
output.push(qb.front());
cnt = 0;
qb.pop();
}
}
while (!qb.empty())
{
output.push(qb.front());
qb.pop();
}
for (int i = 0; i < n; i++)
{
if (i)
cout << " ";
cout << output.front();
output.pop();
}
cout << endl;
return 0;
}
问题 C: DS队列+堆栈–数制转换
题目描述
对于任意十进制数转换为k进制,包括整数部分和小数部分转换。整数部分采用除k求余法,小数部分采用乘k取整法例如x=19.125,求2进制转换
整数部分19, 小数部分0.125
19 / 2 = 9 … 1 0.125 * 2 = 0.25 … 0
9 / 2 = 4 … 1 0.25 * 2 = 0.5 … 0
4 / 2 = 2 … 0 0.5 * 2 = 1 … 1
2 / 2 = 1 … 0
1 / 2 = 0 … 1
所以整数部分转为 10011,小数部分转为0.001,合起来为10011.001
提示整数部分可用堆栈,小数部分可用队列实现
注意:必须按照上述方法来实现数制转换,其他方法0分
输入
第一行输入一个t,表示下面将有t组测试数据。
接下来每行包含两个参数n和k,n表示要转换的数值,可能是非整数;k表示要转换的数制,1<k<=16
输出
对于每一组测试数据,每行输出转换后的结果,结果精度到小数点后3位
输出小数点后几位的代码如下:
#include
#include
using namespace std;
int main()
{
double r = 123.56789;
cout<<fixed<<setprecision(4)<<r<<endl; //输出小数点后4
return 0;
}
样例输入
2
19.125 2
15.125 16
样例输出
10011.001
F.200
AC代码
以下是旧代码,据评论区Going_fall提醒,是有问题的。在小数的乘k取整法中,由于浮点数的精度表示问题,可能会陷入死循环。与此类似的典型案例是美国人设计的0.1秒计时的飞毛腿导弹系统事故,兹不赘述。一个可能的做法是限制小数的乘k取整法的迭代次数。
#include<bits/stdc++.h>
using namespace std;
int main() {
const char num[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
int n000;
cin >> n000;
while (n000--)
{
double t;
int n;
cin >> t >> n;
int z = (int)t;
double x = t - (int)t;
stack<char>ans_z;
queue<char>ans_x;
while (z)
{
ans_z.push(num[z % n]);
z /= n;
}
while (x)
{
x *= n;
ans_x.push(num[(int)x]);
x = x - (int)x;
}
string ans;
while (!ans_z.empty())
{
ans += ans_z.top();
ans_z.pop();
}
ans += '.';
while (!ans_x.empty())
{
ans += ans_x.front();
ans_x.pop();
}
int pos = ans.find('.');
if (ans.length() - pos - 1 > 3)
ans = ans.substr(0, pos + 4);
while (ans.length() - pos - 1 < 3)
ans += "0";
cout << ans << endl;
}
return 0;
}
修改代码如下。
#include<bits/stdc++.h>
using namespace std;
int main() {
const char num[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
int n000;
cin >> n000;
while (n000--) {
double t;
int n;
cin >> t >> n;
int z = (int) t;
double x = t - (int) t;
stack<char> ans_z;
queue<char> ans_x;
while (z) {
ans_z.push(num[z % n]);
z /= n;
}
int xlimit = 5;
while (x && xlimit--) {
x *= n;
ans_x.push(num[(int) x]);
x = x - (int) x;
}
string ans;
while (!ans_z.empty()) {
ans += ans_z.top();
ans_z.pop();
}
ans += '.';
while (!ans_x.empty()) {
ans += ans_x.front();
ans_x.pop();
}
int pos = ans.find('.');
if (ans.length() - pos - 1 > 3)
ans = ans.substr(0, pos + 4);
while (ans.length() - pos - 1 < 3)
ans += "0";
cout << ans << endl;
}
return 0;
}
问题 D: DS队列–组队列
题目描述
组队列是队列结构中一种常见的队列结构,在很多地方有着广泛应用。组队列是是指队列内的元素分组聚集在一起。组队列包含两种命令:
1、 ENQUEUE,表示当有新的元素进入队列,首先会检索是否有同一组的元素已经存在,如果有,则新元素排在同组的最后,如果没有则插入队列末尾。
2、 DEQUEUE,表示队列头元素出队
3、 STOP,停止操作
建议使用C++自带的队列对象queue,编程更方便
输入
第1行输入一个t(t<=10),表示1个队列中有多少个组
第2行输入一个第1组的元素个数和数值
第3行输入一个第2组的元素个数和数值
以此类推输入完t组以定义同组元素之后,开始输入多个操作命令(<200),对空的组队列进行操作,例如输入ENQUEUE 100,表示把元素100插入队列
输出
DEQUEUE出队的元素
样例输入
2
3 101 102 103
3 201 202 203
ENQUEUE 101
ENQUEUE 201
ENQUEUE 102
ENQUEUE 202
ENQUEUE 103
ENQUEUE 203
DEQUEUE
DEQUEUE
DEQUEUE
STOP
样例输出
101 102 103
AC代码
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
map<int, int>mapp;
vector<queue<int>>q(n);
queue<int>shu_zu;
for (int i = 0; i < n; i++) {
int t;
cin >> t;
for (int j = 0; j < t; j++)
{
int temp;
cin >> temp;
mapp[temp] = i;
}
}
vector<int>shuchu;
while (true)
{
string str;
cin >> str;
if (str == "STOP")
break;
if (str == "ENQUEUE")
{
int t;
cin >> t;
if (q[mapp[t]].empty())
shu_zu.push(mapp[t]);
q[mapp[t]].push(t);
}
else
{
int i = shu_zu.front();
shuchu.push_back(q[i].front());
q[i].pop();
if (q[i].empty())
shu_zu.pop();
}
}
for (int i = 0; i < shuchu.size(); i++)
{
if (i)
cout << " ";
cout << shuchu[i];
}
cout << endl;
return 0;
}
问题 E: DS队列----银行单队列多窗口模拟
题目描述
假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙。当有窗口空闲时,下一位顾客即去该窗口处理事务。当有多个窗口可选择时,假设顾客总是选择编号最小的窗口。
本题要求输出前来等待服务的N位顾客的平均等待时间、最长等待时间、最后完成时间。
输入
输入第1行给出正整数N(≤1000),为顾客总人数;随后N行,每行给出一位顾客的到达时间T和事务处理时间P,并且假设输入数据已经按到达时间先后排好了顺序;最后一行给出正整数K(≤10),为开设的营业窗口数。
输出
在一行中输出平均等待时间(输出到小数点后1位)、最长等待时间、最后完成时间,之间用1个空格分隔,行末不能有多余空格。
样例输入
9
0 20
1 15
1 61
2 10
10 5
10 3
30 18
31 25
31 2
3
样例输出
6.2 17 62
AC代码
#include<bits/stdc++.h>
using namespace std;
class Guke {
int arrive, manage;
int start;
public:
Guke() { cin >> arrive >> manage; }
int get_wait_time() { return start - arrive; }
void set_start(int start) { this->start = start; }
int get_art() { return arrive; }
int get_leave_t() { return start + manage; }
};
int main() {
int n, k;
cin >> n;
queue<Guke>q;
for (int i = 0; i < n; i++)
q.push(Guke());
cin >> k;
vector<int>v(k);
int cur_time = 0, max_wait_time = 0, sum_wait_time = 0;
while (!q.empty() || !v.empty())
{
sort(v.begin(), v.end());
while (!v.empty())
{
if (v[0] == cur_time)
v.erase(v.begin());
else
break;
}
while (!q.empty())
{
Guke cur_Guke = q.front();
if (v.size() < k && cur_Guke.get_art() <= cur_time)
{
q.pop();
cur_Guke.set_start(cur_time);
sum_wait_time += cur_Guke.get_wait_time();
if (cur_Guke.get_wait_time() > max_wait_time)
max_wait_time = cur_Guke.get_wait_time();
v.push_back(cur_Guke.get_leave_t());
}
else
break;
}
cur_time += 1;
}
cout << fixed << setprecision(1) << 1.0 * sum_wait_time / n << " " << max_wait_time << " ";
cout << cur_time - 1 << endl;
return 0;
}