数据结构OJ实验4-队列

2024-01-03 19:31:39

A. DS队列之银行排队

题目描述

在银行营业大厅共服务3种客户,类型为A\B\C,大厅分别设置了3个窗口分别服务三种客户,即每个窗口只服务一种客户。现有一批客户来银行办理业务,每个客户都有类型和办理业务时间。每个窗口按照客户到来的顺序进行服务。

编程实现它们的办理流程,请使用C++自带的queue必须使用队列实现,其他方法0分!

队列queue的用法如下:

1.包含头文件:#include <queue>

2.定义一个整数队列对象:queue<int> ?myQe;

3.定义一个整数队列对象数组:queue<int> ?myQA[10];

4.入队操作:myQe.push(itemp); //把整数itemp进入队列

5.出队操作:myQe.pop(); ?//把队头元素弹出队列,注意本操作不获取队头元素

6.获取队头元素: itemp = myQe.front(); // 把队头元素放入itemp中,注意本操作不弹出元素

7.判断队列是否为空:myQe.empty();//队列空则返回true,不空则返回false

输入

第一行输入先输入n表示客户数量

第二行输入每个客户的类型,数据之间用用空格隔开

第三行输入每个客户的办理时间,数据之间用用空格隔开

输出

第一行输出A类客户的平均办理时间

第二行输出B类客户的平均办理时间

第三行输出C类客户的平均办理时间

样例查看模式?

正常显示查看格式

输入样例1?

8
A?B?C?B?C?A?A?A
10?20?30?40?50?60?70?80

输出样例1

55
30
40

AC代码

#include<iostream>
#include<queue>
#include<map>
using namespace std;
int main()
{
	int n;
	cin >> n;
	queue<char>q;
	map<int, int>mp;
	for (int i = 0; i < n; i++)
	{
		char x;
		cin >> x;
		q.push(x);
	}
	for (int i = 0; i < n; i++)
	{
		int x;
		cin >> x;
		mp[i] = x;
	}
	int sumA = 0,cntA=0;
	int sumB = 0,cntB=0;
	int sumC = 0,cntC=0;
	int idx = 0;
	while (!q.empty())
	{
		auto t = q.front();
		q.pop();
		if (t == 'A')
		{
			sumA += mp[idx];
			cntA++;
		}
		else if (t == 'B')
		{
			sumB += mp[idx];
			cntB++;
		}
		else
		{
			sumC += mp[idx];
			cntC++;
		}
		idx++;
	}
	cout << sumA / cntA << endl;
	cout << sumB / cntB << endl;
	cout << sumC / cntC << endl;
	return 0;
}

B. 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 <iostream>
#include <iomanip>
using namespace std;

int main()
{
double r = 123.56789;
cout<<fixed<<setprecision(4)<<r<<endl;?? //输出小数点后4

return 0;
}

样例查看模式?

正常显示查看格式

输入样例1?

2
19.125?2
15.125?16

输出样例1

10011.001
F.200

AC代码

#include<iostream>
#include<queue>
#include<stack>
#include<iomanip>
using namespace std;
char num[18] = {
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F' };//最多16进制
void transform(double n, int k)
{
	//整数->先除的为个位(最后输出)->栈
	//小数->先乘的为首位(首先输出)->队列
	stack<char>z;
	queue<char>x;
	int zhen = (int)n;
	double fen = n - zhen;
	while (zhen != 0)
	{
		z.push(num[zhen % k]);
		zhen /= k;
	}
	int check = 5;//可能取不到0
	while (fen != 0)
	{
		check--;
		if (check == 1)break;
		fen *= k;
		x.push(num[(int)fen]);
		fen = fen - (int)fen;
	}
    if (z.empty())
    {
        cout << "0.";
    }
    else
    {
        while (!z.empty())
        {
            cout << z.top();//最后即首个
            z.pop();
        }
        cout << ".";
    }
    if (x.empty())
    {
        cout << "000";
    }
    else
    {
        for (int i = 1; i <= 3; i++)
        {
            if (x.empty())
            {
                cout << "0";
            }
            else
            {
                cout << x.front();
                x.pop();
            }
        }
    }
    cout << endl;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		double n;
		int k;
		cin >> n >> k;
        transform(n, k);
	}
	return 0;
}

C. 银行业务队列简单模拟

题目描述

设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。

输入

输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。

输出

按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。

样例查看模式?

正常显示查看格式

输入样例1?

8?2?1?3?9?4?11?13?15

输出样例1

1?3?2?9?11?4?13?15

AC代码

#include<iostream>
#include<queue>
#include<stack>
#include<iomanip>
using namespace std;
int main()
{
	int n;
	cin >> n;
	queue<int>a;
	queue<int>b;
	vector<int>ans;
	for (int i = 0; i < n; i++)
	{
		int x;
		cin >> x;
		if (x % 2)a.push(x);
		else b.push(x);
	}
	int cnt = 0;
	while (!a.empty())
	{
		ans.push_back(a.front());
		a.pop();
		cnt++;
		if (cnt == 2)
		{
			if (!b.empty())
			{
				ans.push_back(b.front());
				b.pop();
			}
			cnt = 0;
		}
	}
	while (!b.empty())
	{
		ans.push_back(b.front());
		b.pop();
	}
	for (int i = 0; i < n; i++)
	{
		cout << ans[i];
		if (i != n - 1)cout << " ";
		else cout << endl;
	}
	return 0;
}

D. 银行排队问题之单队列多窗口加VIP服务

题目描述

假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙。当有窗口空闲时,下一位顾客即去该窗口处理事务。当有多个窗口可选择时,假设顾客总是选择编号最小的窗口。

有些银行会给VIP客户以各种优惠服务,例如专门开辟VIP窗口。为了最大限度地利用资源,VIP窗口的服务机制定义为:当队列中没有VIP客户时,该窗口为普通顾客服务;当该窗口空闲并且队列中有VIP客户在等待时,排在最前面的VIP客户享受该窗口的服务。同时,当轮到某VIP客户出列时,若VIP窗口非空,该客户可以选择空闲的普通窗口;否则一定选择VIP窗口。

本题要求输出前来等待服务的N位顾客的平均等待时间、最长等待时间、最后完成时间,并且统计每个窗口服务了多少名顾客。

输入

输入第1行给出正整数N(≤1000),为顾客总人数;随后N行,每行给出一位顾客的到达时间T、事务处理时间P和是否VIP的标志(1是VIP,0则不是),并且假设输入数据已经按到达时间先后排好了顺序;最后一行给出正整数K(≤10)—— 为开设的营业窗口数,以及VIP窗口的编号(从0到K?1)。这里假设每位顾客事务被处理的最长时间为60分钟。

输出

在第一行中输出平均等待时间(输出到小数点后1位)、最长等待时间、最后完成时间,之间用1个空格分隔,行末不能有多余空格。

在第二行中按编号递增顺序输出每个窗口服务了多少名顾客,数字之间用1个空格分隔,行末不能有多余空格。

样例查看模式?

正常显示查看格式

输入样例1?

10
0?20?0
0?20?0
1?68?1
1?12?1
2?15?0
2?10?0
3?15?1
10?12?1
30?15?0
62?5?1
3?1

输出样例1

15.1?35?67
4?5?1

AC代码

#include<bits/stdc++.h>
using namespace std;
struct people
{
    int arrive;
    int manage;
    int VIP;
};
int main()
{
    int n;
    cin>>n;
    vector<people>v;
    for(int i=0;i<n;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        b=min(60,b);
        v.push_back({a,b,c});
    }
    int k,vk;
    cin>>k>>vk;
    vector<int>server(k,0);
    vector<int>deal(k,0);
    int max_wait=0;
    int finish=0;
    double avg_wait=0;
    int cur=0;
    while(1)
    {
        //先处理vip
        if(deal[vk]==0)
        {
            for(vector<people>::iterator it=v.begin();it!=v.end();it++)
            {
                auto p=(*it);
                if(p.VIP&&p.arrive<=cur)
                {
                    server[vk]++;
                    deal[vk]=p.manage;
                    int need=cur-p.arrive;
                    finish+=need;
                    if(need>max_wait)
                    {
                        max_wait=need;
                    }
                    v.erase(it);
                    break;
                }
            }
        }
        //后处理其它人
        while(!v.empty()&&v.front().arrive<=cur)
        {
            auto tt=v.front();
            bool flag=0;
            for(int i=0;i<k;i++)
            {
                if(deal[i]==0)
                {
                    server[i]++;
                    deal[i]=tt.manage;
                    int need=cur-tt.arrive;
                    finish+=need;
                    if(need>max_wait)
                    {
                        max_wait=need;
                    }
                    v.erase(v.begin());
                    flag=1;
                    break;
                }
            }
            //所有窗口都有人
            if(!flag)
            {
                break;
            }
        }
        bool flag1=0;
        for(int i=0;i<k;i++)
        {
            //在办理中
            if(deal[i])deal[i]--;
            if(deal[i])flag1=1;
        }
        cur++;
        if(!flag1&&v.empty())
        {
            break;
        }
    }
    printf("%.1lf %d %d\n",1.0*finish/n,max_wait,cur);
    for(int i=0;i<k;i++)
    {
        if(i)cout<<" ";
        cout<<server[i];
    }
    cout<<endl;
    return 0;
}

E. DS栈+队列—排队游戏

题目描述

在幼儿园中,老师安排小朋友做一个排队的游戏。首先老师精心的把数目相同的小男孩和小女孩编排在一个队列中,每个小孩按其在队列中的位置发给一个编号(编号从0开始)。然后老师告诉小朋友们,站在前边的小男孩可以和他后边相邻的小女孩手拉手离开队列,剩余的小朋友重新站拢,再按前后相邻的小男孩小女孩手拉手离开队列游戏,如此往复。由于教师精心的安排,恰好可以保证每两个小朋友都能手拉手离开队列,并且最后离开的两个小朋友是编号最小的和最大的两个小朋友。(注:只有小男孩在前,小女孩在后,且他们两之间没有其他的小朋友,他们才能手拉手离开队列)。请根据老师的排队,按小女孩编号从小到大的顺序,给出所有手拉手离开队列的小男孩和小女孩的编号对。

输入

用一个字符串代表小朋友队列。字符串中只会出现两个字符,分别代表小男孩和小女孩,首先出现的字符代表小男孩,另一个字符代表小女孩。小孩总数不超过2000。

输出

按小女孩编号顺序,顺序输出手拉手离开队列的小男孩和小女孩的编号对,每行一对编号,编号之间用一个空格分隔。

样例查看模式?

正常显示查看格式

输入样例1?

((()(())())(()))

输出样例1

2?3
5?6
4?7
8?9
1?10
12?13
11?14
0?15


AC代码

#include<iostream>
#include<queue>
#include<stack>
#include<iomanip>
using namespace std;
int main()
{
	string s;
	cin >> s;
	stack<pair<char, int>>q;
	for (int i = 0; i < s.size(); i++)
	{
		if (s[i] == '(')
		{
			q.push({ '(',i });
		}
		else
		{
			auto t = q.top();
			q.pop();
			cout << t.second << " " << i << endl;
		}
	}
	return 0;
}

F. DS队列--组队列

题目描述

组队列是队列结构中一种常见的队列结构,在很多地方有着广泛应用。组队列是是指队列内的元素分组聚集在一起。组队列包含两种命令:

1、 ENQUEUE,表示当有新的元素进入队列,首先会检索是否有同一组的元素已经存在,如果有,则新元素排在同组的最后,如果没有则插入队列末尾。

2、 DEQUEUE,表示队列头元素出队

3、 STOP,停止操作

输入

第1行输入一个t(t<=10),表示1个队列中有多少个组

第2行输入一个第1组的元素个数和数值

第3行输入一个第2组的元素个数和数值

以此类推输入完t组以定义同组元素之后,开始输入多个操作命令(<200),对空的组队列进行操作,例如输入ENQUEUE 100,表示把元素100插入队列

输出

DEQUEUE出队的元素

样例查看模式?

正常显示查看格式

输入样例1?

2\n
3?101?102?103\n
3?201?202?203\n
ENQUEUE?101\n
ENQUEUE?201\n
ENQUEUE?102\n
ENQUEUE?202\n
ENQUEUE?103\n
ENQUEUE?203\n
DEQUEUE\n
DEQUEUE\n
DEQUEUE\n
STOP\n

输出样例1

101?102?103\n

输入样例2?

3\n
3?101?102?103\n
3?201?202?203\n
3?301?302?303\n
ENQUEUE?201\n
ENQUEUE?301\n
ENQUEUE?102\n
DEQUEUE\n
DEQUEUE\n
DEQUEUE\n
ENQUEUE?101\n
ENQUEUE?203\n
ENQUEUE?302\n
ENQUEUE?301\n
DEQUEUE\n
DEQUEUE\n
DEQUEUE\n
STOP\n

AC代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    vector<queue<int>>q(n);
    map<int,int>mp;
    queue<int>num;
    vector<int>res;
    for(int i=0;i<n;i++)
    {
        int nn;
        cin>>nn;
        for(int j=0;j<nn;j++)
        {
            int tt;
            cin>>tt;
            mp[tt]=i;//每个对应的组数
        }
    }
    string ans;
    while(1)
    {
        cin>>ans;
        if(ans=="STOP")break;
        else if(ans=="ENQUEUE")
        {
            int pp;
            cin>>pp;
            if(q[mp[pp]].empty())
            {
                num.push(mp[pp]);
            }
            q[mp[pp]].push(pp);
        }
        else
        {
            int kk=num.front();
            res.push_back(q[kk].front());
            q[kk].pop();
            if(q[kk].empty())
            {
                num.pop();
            }
        }
    }
    for(int i=0;i<res.size();i++)
    {
         if(i)cout<<" ";
        cout<<res[i];
    }
    cout<<endl;
    return 0;
}

文章来源:https://blog.csdn.net/gyeolhada/article/details/135322510
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。