深圳大学计软《数据结构》实验05--队列

问题 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;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曹无悔

请支持我的梦想!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值