Delete 可供参考资料_zyx/银行排队问题.cpp
This commit is contained in:
parent
0a309fd843
commit
9bf98038c2
@ -1,272 +0,0 @@
|
|||||||
//问题2-2
|
|
||||||
#include <iostream>
|
|
||||||
#include <ctime>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#define Status int
|
|
||||||
#define OVERFLOW 2
|
|
||||||
#define ERROR 1
|
|
||||||
#define OK 0;
|
|
||||||
typedef int QElemType;
|
|
||||||
|
|
||||||
int queue_number[10] = { 0 };//queue_number记录队列人数
|
|
||||||
int i, j = 0;//i用于客户计数,j用于窗口计数
|
|
||||||
int no = 0;//no用于记录客户序号,其中第一位客户的序号为1
|
|
||||||
int time_length = 0;//time_length记录模拟程序运行时长
|
|
||||||
int window_number = 0;
|
|
||||||
|
|
||||||
typedef struct QNode
|
|
||||||
{
|
|
||||||
int no;//序号
|
|
||||||
double amount;//总金额
|
|
||||||
double remain_amount;//未取金额(不计当前轮)
|
|
||||||
struct QNode* next;
|
|
||||||
}QNode, * QueuePtr;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
QueuePtr front; //队头指针
|
|
||||||
QueuePtr rear; //队尾指针
|
|
||||||
}LinkQueue;
|
|
||||||
|
|
||||||
Status InitQueue(LinkQueue& Q)
|
|
||||||
{
|
|
||||||
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
|
|
||||||
if (!Q.front) exit(OVERFLOW);
|
|
||||||
Q.front->next = NULL;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status DestroyQueue(LinkQueue& Q)
|
|
||||||
{
|
|
||||||
while (Q.front)
|
|
||||||
{
|
|
||||||
Q.rear = Q.front->next;
|
|
||||||
free(Q.front);
|
|
||||||
Q.front = Q.rear;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status QueueEmpty(LinkQueue Q)
|
|
||||||
{
|
|
||||||
return (Q.front == Q.rear);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status GetHead(LinkQueue Q, int& e1, double& e2, double& e3)
|
|
||||||
{
|
|
||||||
if (Q.front == Q.rear) return ERROR;
|
|
||||||
e1 = Q.front->next->no;
|
|
||||||
e2 = Q.front->next->amount;
|
|
||||||
e3 = Q.front->next->remain_amount;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status EnQueue(LinkQueue& Q, int& e1, double& e2, double& e3)
|
|
||||||
{
|
|
||||||
QueuePtr p;
|
|
||||||
p = (QueuePtr)malloc(sizeof(QNode));
|
|
||||||
if (!p) exit(OVERFLOW);
|
|
||||||
p->no = e1;
|
|
||||||
p->amount = e2;
|
|
||||||
p->remain_amount = e3;
|
|
||||||
p->next = NULL;
|
|
||||||
Q.rear->next = p;
|
|
||||||
Q.rear = p;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status DeQueue(LinkQueue& Q, int& e1, double& e2, double& e3)
|
|
||||||
{
|
|
||||||
if (Q.front == Q.rear) return ERROR;
|
|
||||||
QueuePtr p;
|
|
||||||
p = Q.front->next;
|
|
||||||
e1 = p->no;
|
|
||||||
e2 = p->amount;
|
|
||||||
e3 = p->remain_amount;
|
|
||||||
Q.front->next = p->next;
|
|
||||||
if (Q.rear == p) Q.rear = Q.front;
|
|
||||||
delete p;
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MinQueue()
|
|
||||||
{
|
|
||||||
int s = 10000, k = 0, temp;
|
|
||||||
for (k = 0;k < window_number;k++)
|
|
||||||
{
|
|
||||||
if (queue_number[k] < s)
|
|
||||||
{
|
|
||||||
temp = k;
|
|
||||||
s = queue_number[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MaxQueue()
|
|
||||||
{
|
|
||||||
int s = -1, k = 0, temp;
|
|
||||||
for (k = 0;k < window_number;k++)
|
|
||||||
{
|
|
||||||
if (queue_number[k] > s)
|
|
||||||
{
|
|
||||||
temp = k;
|
|
||||||
s = queue_number[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Remove(LinkQueue& Q)//检查第一个人是否已取完。注意判断队列是否为空。
|
|
||||||
{
|
|
||||||
if (!QueueEmpty(Q))
|
|
||||||
{
|
|
||||||
if (Q.front->next->remain_amount <= 1e-8)
|
|
||||||
{
|
|
||||||
int e1 = -1;
|
|
||||||
double e2 = -1, e3 = -1;
|
|
||||||
DeQueue(Q, e1, e2, e3);
|
|
||||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
|
|
||||||
FOREGROUND_INTENSITY | FOREGROUND_GREEN);//设置绿色
|
|
||||||
cout << "第" << (double)i / 10 + 0.1 << "秒时" << j + 1 << "号窗口"
|
|
||||||
<< "第" << e1 << "位客户完成业务,取走共" << e2 << "万元。" << endl;
|
|
||||||
queue_number[j]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Join(LinkQueue* q)
|
|
||||||
{
|
|
||||||
int a = rand() % 60;
|
|
||||||
//a的值在0-60之间随机分布,只有当a=0到window_number-1时才产生新客户
|
|
||||||
//平均每6秒产生window_number个客户,与窗口数量对应
|
|
||||||
if (a < window_number)
|
|
||||||
{
|
|
||||||
no++;
|
|
||||||
double b = double(rand() % 191) / 10 + 1;//b的值在1-20之间随机分布(精度0.1),代表用户取钱的金额数(单位:万元)
|
|
||||||
int m = MinQueue();
|
|
||||||
EnQueue(q[m], no, b, b);
|
|
||||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
|
|
||||||
FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);//设置红色和绿色相加
|
|
||||||
cout << "第" << (double)i / 10 + 0.1 << "秒时第" << no << "位客户进入窗口"
|
|
||||||
<< m + 1 << "队列,需取" << b << "万元。" << endl;
|
|
||||||
queue_number[m]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChangeQuene(LinkQueue* q)
|
|
||||||
{
|
|
||||||
int min = MinQueue(), max = MaxQueue();
|
|
||||||
while (queue_number[max] - queue_number[min] >= 2)
|
|
||||||
{
|
|
||||||
int e1;
|
|
||||||
double e2, e3;
|
|
||||||
DeQueue(q[max], e1, e2, e3);
|
|
||||||
EnQueue(q[min], e1, e2, e3);
|
|
||||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
|
|
||||||
FOREGROUND_INTENSITY | FOREGROUND_BLUE);//设置蓝色
|
|
||||||
cout << "第" << e1 << "位客户从窗口" << max + 1 << "队列调整到窗口" << min + 1 << "队列" << endl;
|
|
||||||
|
|
||||||
queue_number[min]++;
|
|
||||||
queue_number[max]--;
|
|
||||||
min = MinQueue();
|
|
||||||
max = MaxQueue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Withdraw(LinkQueue& Q)
|
|
||||||
{
|
|
||||||
if (!QueueEmpty(Q) && i != time_length)
|
|
||||||
{
|
|
||||||
Q.front->next->remain_amount -= 0.2;//每0.1秒取走0.2万
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Undone(LinkQueue& Q)
|
|
||||||
{
|
|
||||||
while (!QueueEmpty(Q))
|
|
||||||
{
|
|
||||||
int e1 = -1;
|
|
||||||
double e2 = -1, e3 = -1;
|
|
||||||
DeQueue(Q, e1, e2, e3);
|
|
||||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
|
|
||||||
FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);//设置绿色和蓝色相加
|
|
||||||
cout << "窗口" << j + 1 << "队列第" << e1 <<
|
|
||||||
"位客户未完成业务,未取共" << e2 << "万元。" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
cout << "请输入模拟程序运行时长(单位:秒)(1-300之间的整数):" << endl;
|
|
||||||
//time_length = 120;
|
|
||||||
cin >> time_length;
|
|
||||||
while (time_length <= 0 || time_length > 300)
|
|
||||||
{
|
|
||||||
cout << "您输入的时间不符合要求,请重新输入:";
|
|
||||||
cin >> time_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "请输入银行窗口数(1-10之间的整数):" << endl;
|
|
||||||
cin >> window_number;
|
|
||||||
while (window_number <= 0 || window_number > 10)
|
|
||||||
{
|
|
||||||
cout << "您输入的窗口数不符合要求,请重新输入:";
|
|
||||||
cin >> window_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
LinkQueue* q = (LinkQueue*)malloc(window_number * sizeof(LinkQueue));
|
|
||||||
|
|
||||||
//队列初始化
|
|
||||||
for (j = 0;j < window_number;j++)
|
|
||||||
{
|
|
||||||
InitQueue(q[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
srand(time(nullptr));//设置随机数种子
|
|
||||||
|
|
||||||
//核心代码
|
|
||||||
for (i = 0;i <= time_length * 10;i++)//每0.1秒循环一次,直到到达预定时间
|
|
||||||
{
|
|
||||||
//先检查第一个人是否已取完。注意判断队列是否为空
|
|
||||||
for (j = 0;j < window_number;j++)
|
|
||||||
{
|
|
||||||
Remove(q[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//再把新客户加到人最少的队伍
|
|
||||||
Join(q);
|
|
||||||
|
|
||||||
//再判定是否有客户需要重新选择队列
|
|
||||||
ChangeQuene(q);
|
|
||||||
|
|
||||||
//再给当前队伍第一位取钱,注意判断队列是否为空
|
|
||||||
//注意i=time_length时取钱业务已经停止
|
|
||||||
for (j = 0;j < window_number;j++)
|
|
||||||
{
|
|
||||||
Withdraw(q[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sleep(93);
|
|
||||||
//100单位为毫秒,即0.1秒。考虑到程序运行时间,将100改为93
|
|
||||||
//由于Sleep()函数的精度不高,因此循环间隔不能太小
|
|
||||||
}
|
|
||||||
|
|
||||||
//程序结束前,输出未取完钱的人的情况
|
|
||||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
|
|
||||||
FOREGROUND_INTENSITY);//设置颜色,没有添加颜色,故为原色
|
|
||||||
cout << endl << "取钱业务结束。" << endl << endl;
|
|
||||||
for (j = 0;j < window_number;j++)
|
|
||||||
{
|
|
||||||
Undone(q[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
|
|
||||||
FOREGROUND_INTENSITY);//设置颜色,没有添加颜色,故为原色
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user