银行业务办理

编程题目(队列练习)

2022.10.17

模拟银行办理业务系统。银行有3个窗口,第一个窗口只能办理业务1,第二个窗口只能办理业务2,第三个窗口既能办理业务1也能办理业务2. 顾客到达银行时具有如下信息:到达时间、业务类型(1或者2)、办理该业务所需要的时间。

具体要求

  1. 顾客会根据窗口业务类型和前面排队人数选择相应窗口,如业务类型1只能在1号和3号窗口办理。
  2. 顾客不知道前面顾客业务办理所需要的时间,但是可以根据等待人数多少调整窗口。
  3. 对于业务类型1,如果第一个窗口和第三个窗口人数相同,先在第一个窗口等待。
  4. 对于业务类型2,如果第二个窗口和第三个窗口人数相同,先在第二个窗口等待。

样例输入数据:

3 (窗口个数)

1 1 3(到达时间、业务类型、办理需要的时间,分钟为单位)

1 2 3

2 1 5

2 1 8

4 2 1

4 1 2

代码

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
	int arriveTime;//到达时间
	int type;//办理类型
	int spendTime;//办理时间
	int waitTime;//等待时间
	LNode* next;
	LNode* before = NULL;//上一个结点
};
typedef struct LinkQueue
{
	LNode* front;
	LNode* rear;
	int size;//队列大小
};
void InitQueue(LinkQueue& q)//初始化队列
{
	q.front = q.rear = (LNode*)malloc(sizeof(LNode));
	if (q.front == NULL)
	{
		exit(0);
	}
	q.front->next = NULL;
	q.size = 0;
}
void EnQueue(LinkQueue& q, int e,int f ,int g)//入队
{
	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL)exit(0);
	s->arriveTime = e;
	s->type = f;
	s->spendTime = g;
	q.rear->next = s;
	s->before = q.rear;
	q.rear = s;
	q.size++;
	q.rear->next = NULL;
}
LNode* DeQueue(LinkQueue& q)//从队首出队
{
	if (q.front == q.rear)return NULL;
	LNode* p = q.front->next;
	q.front->next = p->next;
	if (q.rear == p)
		q.rear = q.front;
	q.size--;
	return p;

}
LNode* DeQueue2(LinkQueue& q)//从队尾出队
{
	if (q.front == q.rear)return NULL;
	LNode* p = q.rear->before;
	LNode* m=q.rear;
	q.rear = p;
	q.size--;
	q.rear->next = NULL;
	return m;
}
int main()
{
	int num;
	printf("请输入操作次数:\n");
	scanf_s("%d", &num);
	int a[10][3];
	printf("请输入操作:\n");
	for (int i = 0;i < num;i++)
	{
		for (int j = 0;j < 3;j++)
		{
			scanf_s("%d", &a[i][j]);
		}
	}
	LinkQueue q1, q2, q3;
	InitQueue(q1);
	InitQueue(q2);
	InitQueue(q3);
	int t = 1, i = 0;
	while (t)
	{
		if (a[i][0] < t&&i<num&&i>=0)//当到达时间小于计时的时间时,计时时间减一,再循环
		{
			t --;
			continue;
		}
		//当等待时间+办理时间+到达时间等于计时时间时出队
		if (q1.size!=0)
		{
			if (q1.front->next->waitTime + q1.front->next->spendTime == t-q1.front->next->arriveTime)
			{
				LNode* p=DeQueue(q1);
				printf("(%d,%d,%d)离开队伍一\n", p->arriveTime, p->type, p->spendTime);
			}
		}
		if (q2.size!=0)
		{
			if (q2.front->next->waitTime + q2.front->next->spendTime == t-q2.front->next->arriveTime)
			{
				LNode *p=DeQueue(q2);
				printf("(%d,%d,%d)离开队伍二\n", p->arriveTime, p->type, p->spendTime);
			}
		}
		if (q3.size!=0)
		{
			if (q3.front->next->waitTime + q3.front->next->spendTime == t-q3.front->next->arriveTime)
			{
				LNode *p=DeQueue(q3);
				printf("(%d,%d,%d)离开队伍三\n", p->arriveTime, p->type, p->spendTime);
			}
		}
		//转队操作	
		if (q1.size > q3.size + 1)
		{
			LNode* p = DeQueue2(q1);
			if (q3.size == 0)
			{
				EnQueue(q3, p->arriveTime, p->type, p->spendTime);
				q3.rear->waitTime = t-p->arriveTime;
				printf("窗口一转到窗口三:(%d %d %d)\n", q3.rear->arriveTime, q3.rear->type, q3.rear->spendTime);

			}
			else
			{
				int t1 = q3.rear->waitTime;
				int t2 = q3.rear->spendTime;
				int t3 = q3.rear->arriveTime;
				EnQueue(q3, p->arriveTime, p->type, p->spendTime);
				if (t1 + t2 - (t - t3) > 0)
					q3.rear->waitTime = t1 + t2 - (t - t3)+t-p->arriveTime;
				else
				{
					q3.rear->waitTime = t - p->arriveTime;
				}
				printf("窗口一转到窗口三:(%d %d %d)\n",q3.rear->arriveTime,q3.rear->type,q3.rear->spendTime);
			}

		}
		if (q3.size > q1.size + 1)
		{
			LNode* p = DeQueue2(q3);
			if (q1.size == 0)
			{
				EnQueue(q1, p->arriveTime, p->type, p->spendTime);
				q1.rear->waitTime = t - p->arriveTime;
				printf("窗口三转到窗口一:(%d %d %d)\n", q3.rear->arriveTime, q3.rear->type, q3.rear->spendTime);

			}
			else
			{
				int t1 = q1.rear->waitTime;
				int t2 = q1.rear->spendTime;
				int t3 = q1.rear->arriveTime;
				EnQueue(q1, p->arriveTime, p->type, p->spendTime);
				if (t1 + t2 - (t - t3) > 0)
					q1.rear->waitTime = t1 + t2 - (t - t3) + t - p->arriveTime;
				else
				{
					q1.rear->waitTime = t - p->arriveTime;
				}
				printf("窗口三转到窗口一:(%d %d %d)\n", q3.rear->arriveTime, q3.rear->type, q3.rear->spendTime);
			}

		}
		if (q2.size > q3.size + 1)
		{
			LNode* p = DeQueue2(q2);
			if (q3.size == 0)
			{
				EnQueue(q3, p->arriveTime, p->type, p->spendTime);
				q3.rear->waitTime = t - p->arriveTime;
				printf("窗口二转到窗口三:(%d %d %d)\n", q3.rear->arriveTime, q3.rear->type, q3.rear->spendTime);

			}
			else
			{
				int t1 = q3.rear->waitTime;
				int t2 = q3.rear->spendTime;
				int t3 = q3.rear->arriveTime;
				EnQueue(q3, p->arriveTime, p->type, p->spendTime);
				if (t1 + t2 - (t - t3) > 0)
					q3.rear->waitTime = t1 + t2 - (t - t3) + t - p->arriveTime;
				else
				{
					q3.rear->waitTime = t - p->arriveTime;
				}
				printf("窗口二转到窗口三:(%d %d %d)\n", q3.rear->arriveTime, q3.rear->type, q3.rear->spendTime);
			}

		}
		if (q3.size > q2.size + 1)
		{
			LNode* p = DeQueue2(q3);
			if (q2.size == 0)
			{
				EnQueue(q2, p->arriveTime, p->type, p->spendTime);
				q2.rear->waitTime = t - p->arriveTime;
				printf("窗口三转到窗口二:(%d %d %d)\n", q2.rear->arriveTime, q2.rear->type, q2.rear->spendTime);

			}
			else
			{
				int t1 = q2.rear->waitTime;
				int t2 = q2.rear->spendTime;
				int t3 = q2.rear->arriveTime;
				EnQueue(q2, p->arriveTime, p->type, p->spendTime);
				if (t1 + t2 - (t - t3) > 0)
					q2.rear->waitTime = t1 + t2 - (t - t3) + t - p->arriveTime;
				else
				{
					q2.rear->waitTime = t - p->arriveTime;
				}
				printf("窗口三转到窗口二:(%d %d %d)\n", q2.rear->arriveTime, q2.rear->type, q2.rear->spendTime);
			}

		}


		//跳出条件
		if (q1.size==0&&q2.size==0&&q3.size==0&&i!=0)
			break;
		//某一计时时间时无人入队
		if (a[i][0] > t&&i<=num&&i>=0)
		{
			t++;
			continue;
		}
		//根据类型入队,相比3窗口,优先1、2窗口
		if (a[i][1] == 1)
		{
			if (q1.size <= q3.size)
			{
				if (q1.size == 0)
				{
					EnQueue(q1, a[i][0], a[i][1], a[i][2]);
					q1.rear->waitTime = 0;
					printf("窗口一:(%d %d %d)\n", a[i][0], a[i][1], a[i][2]);
				}
				else
				{
					int t1 = q1.rear->waitTime;
					int t2 = q1.rear->spendTime;
					int t3 = q1.rear->arriveTime;
					EnQueue(q1, a[i][0], a[i][1], a[i][2]);
					if (t1 + t2 - (t - t3) > 0)
						q1.rear->waitTime = t1 + t2 - (t - t3);
					else
					{
						q1.rear->waitTime = 0;
					}
					printf("窗口一:(%d %d %d)\n", a[i][0], a[i][1], a[i][2]);
				}
				
			}
			else
			{
				if (q3.size == 0)
				{
					EnQueue(q3, a[i][0], a[i][1], a[i][2]);
					q3.rear->waitTime = 0;
					printf("窗口三:(%d %d %d)\n", a[i][0], a[i][1], a[i][2]);
				}
				else
				{
					int t1 = q3.rear->waitTime;
					int t2 = q3.rear->spendTime;
					int t3 = q3.rear->arriveTime;
					EnQueue(q3, a[i][0], a[i][1], a[i][2]);
					if (t1 + t2 - (t - t3) > 0)
						q3.rear->waitTime = t1 + t2 - (t - t3);
					else
					{
						q3.rear->waitTime = 0;
					}
					printf("窗口三:(%d %d %d)\n", a[i][0], a[i][1], a[i][2]);
				}
				

			}
		}
		else if(a[i][1]==2)
		{
			if (q2.size <= q3.size)
			{
				if (q2.size == 0)
				{
					EnQueue(q2, a[i][0], a[i][1], a[i][2]);
					q2.rear->waitTime = 0;
					printf("窗口二:(%d %d %d)\n", a[i][0], a[i][1], a[i][2]);
				}
				else
				{
					int t1 = q2.rear->waitTime;
					int t2 = q2.rear->spendTime;
					int t3 = q2.rear->arriveTime;
					EnQueue(q2, a[i][0], a[i][1], a[i][2]);
					if (t1 + t2 - (t - t3) > 0)
						q2.rear->waitTime = t1 + t2 - (t - t3);
					else
					{
						q2.rear->waitTime = 0;
					}
					printf("窗口二:(%d %d %d)\n", a[i][0], a[i][1], a[i][2]);
				}
				

			}
			else
			{
				if (q3.size == 0)
				{
					EnQueue(q3, a[i][0], a[i][1], a[i][2]);
					q3.rear->waitTime = 0;
					printf("窗口三:(%d %d %d)\n", a[i][0], a[i][1], a[i][2]);
				}
				else
				{
					int t1 = q3.rear->waitTime;
					int t2 = q3.rear->spendTime;
					int t3 = q3.rear->arriveTime;
					EnQueue(q3, a[i][0], a[i][1], a[i][2]);
					if(t1+t2-(t-t3)>0)
					q3.rear->waitTime = t1 + t2 - (t - t3);
					else
					{
						q3.rear->waitTime = 0;
					}
					printf("窗口三:(%d %d %d)\n", a[i][0], a[i][1], a[i][2]);
				}
				

			}
		}
		if (i <= num)
		{
		i++;
		}
		
		t++;

	}

	system("pause");
	return 0;
}

运行结果

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值