/*********************************************************************
    程序名: 银行业务模拟
    版权: java.KFC.CrazyThursday.BalanceNotEnoughException:
			at function getWechatBalance(), getAlipayBalance();
    作者: 筱鸣@1522
    日期: 2022-10-29 17:03
    说明: 模拟简单的银行业务
*********************************************************************/
#include <bits/stdc++.h>
using namespace std;

class Customer {
	private:
		int id;//没用到
		int enterTime;//从9点开始以秒计算的客户进入时间
		//比如10:00:00进入就是3600,09:10:05就是605

	public:
		Customer() {
		}
		Customer(int id, int enterTime) {
			this->id = id;
			this->enterTime = enterTime;
		}
		int getId() {
			return this->id;
		}
		int getEnterTime() {
			return this->enterTime;
		}
} c[105];

class Staff {
	public:
		int remainTime = -1;//每个员工对于当前业务的处理时间
		int count = 0;//经手多少人
		queue<Customer> q;//员工面前的队伍
} s[5];

void timePrint(int seconds) {//以秒数直接计算当前时间并输出
	int h = 0;
	int m = 0;
	int s = 0;
	m = seconds / 60;
	s = seconds % 60;
	h = m / 60;
	m %= 60;
	printf("[%02d:%02d:%02d]:", h + 9, m, s);
}

void timeFilePrint(int seconds, FILE *stream) {//同上,往文件里输出的版本
	int h = 0;
	int m = 0;
	int s = 0;
	m = seconds / 60;
	s = seconds % 60;
	h = m / 60;
	m %= 60;
	fprintf(stream, "[%02d:%02d:%02d]:", h + 9, m, s);
}

bool cmp(Customer a, Customer b) {//使用STL的sort给客户进门的时间不降序排列
	return a.getEnterTime() < b.getEnterTime();
}

void createConditions() {

	for (int i = 1; i <= 100; i++) {
		srand(c[i - 1].getEnterTime()  + time(0));
		//种子越怪越好

		c[i] = Customer(i, rand() % 28801);
		//rand()生成的数字最大为65536 让客户在自09:00:00起28800秒,即17:00:00内进来
	}
	sort(c + 1, c + 101, cmp);

}

pair<int, int> scanQueue() {
	int lowValue = 114514;//跑完循环后出现最少排队人数
	int window = -1;//客户选择的窗口
	//经过测试,生成进入时间时,基本上不会出现"客户蜂拥而至"且"某时段员工处理能力极快"导致某队伍极长且存在窗口空置的情况
	for (int i = 1; i <= 4; i++) {
		if (s[i].q.size() < lowValue) {
			lowValue = s[i].q.size();
			window = i;
		}
	}
	pair<int, int>p(window, lowValue);//返回一个为要选择的窗口,另一个是当前选择的窗口的人数
	return p;
}

//17:00:00为28800秒

int main() {
	FILE *stream;
	//打开文件
	stream = fopen("RECORD.txt", "w");//在该cpp文件所在的位置生成结果
	if (stream != NULL) {

		int total = 0;
		double waitSecond = 0;//总客户等待时间,用于程序末尾的统计
		double staySecond = 0;//总客户逗留时间,用于程序末尾的统计

		createConditions();//创造条件

		int currentCustomer = 1;//指向客户列表的当前客户
		for (int i = 0; i <= 30000 || currentCustomer < 101; i++) {
			//时间宽裕至3w秒 一旦客户列表读完(100人)就跳出循环

			//每秒可能有三种操作:一种是有人进来;一种是有人出去;一种是啥也没发生

			for (int j = 1; j <= 4; j++) { //有人离开
				if (s[j].remainTime == 0) {//员工处理完了

					timePrint(i);
					printf("%02d 号客户在 %d 号窗口办理完成\n", s[j].q.front().getId(), j);
					//s[j]是员工列表,每个员工有一个队列q,q的第一个元素的id是正在办理的客户的id;

					timeFilePrint(i, stream);
					fprintf(stream, "%02d 号客户在 %d 号窗口办理完成\n", s[j].q.front().getId(), j);

					s[j].count++;//经手一个人
					s[j].q.pop();//当前客户离开

					if (s[j].q.size()) {//如果现在的队列里还有人那就上来办业务

						timePrint(i);
						printf("%02d 号客户在 %d 号窗口开始办理\n", s[j].q.front().getId(), j);

						timeFilePrint(i, stream);
						fprintf(stream, "%02d 号客户在 %d 号窗口开始办理\n", s[j].q.front().getId(), j);

						srand( time(0) + s[j].q.front().getEnterTime());
						s[j].remainTime = rand() % (20 * 60 + 1);//给当前的顾客决定一个avg=10min的处理时间
					}

				}
			}
			while (i == c[currentCustomer].getEnterTime()) { //当前时间正好和列表中第一个客户的时间相等,就放他进来
				pair<int, int> choice = scanQueue();//找到客户想去的队伍和他目标队伍的人数

				if (choice.second == 0) { //无需排队直接办理

					//s[选择的窗口].q.push(这一名客户)
					s[choice.first].q.push(c[currentCustomer]);

					timePrint(i);
					printf("%02d 号客户在 %d 号窗口开始办理\n", s[choice.first].q.front().getId(), choice.first);

					timeFilePrint(i, stream);
					fprintf(stream, "%02d 号客户在 %d 号窗口开始办理\n", s[choice.first].q.front().getId(), choice.first);

					srand(time(0) + c[currentCustomer].getEnterTime());
					s[choice.first].remainTime = rand() % (20 * 60 + 1);//给当前的顾客决定一个avg=10min的处理时间

				} else { //排队
					s[choice.first].q.push(c[currentCustomer]);

					timePrint(i);
					printf("%02d 号客户在 %d 号窗口排队\n", c[currentCustomer].getId(), choice.first);

					timeFilePrint(i, stream);
					fprintf(stream, "%02d 号客户在 %d 号窗口排队\n", c[currentCustomer].getId(), choice.first);
				}

				currentCustomer++;//这个客户进来了,换下一个客户急
			}
			for (int j = 1; j <= 4; j++) {//无事发生
				s[j].remainTime--;//每个窗口剩余处理秒数减少1
				if (s[j].q.size() > 1) {
					waitSecond += (s[j].q.size() - 1);
					staySecond += s[j].q.size();
				}
			}
		}

		for (int i = 1; i <= 4; i++) {
			total += s[i].count;
			//	cout << s[i].remainTime << endl;
		}

		printf("今日共办理%d件业务\n", total);
		fprintf(stream, "今日共办理%d件业务\n", total);

		for (int i = 1; i <= 4; i++) {
			printf("%d号窗口办理%d件\n", i, s[i].count);
			fprintf(stream, "%d号窗口办理%d件\n", i, s[i].count);
		}

		printf("客户平均等待%.2lfmin\n", waitSecond / (60 * 100));
		fprintf(stream, "客户平均等待%.2lfmin\n", waitSecond / (60 * 100));

		printf("客户平均逗留%.2lfmin\n", staySecond / (60 * 100));
		fprintf(stream, "客户平均逗留%.2lfmin\n", staySecond / (60 * 100));
	}
	fclose(stream);
	return 0;
}

 调试记录:

好家伙你们这是只排队不办事啊;

 

Android 仿真卡模拟信用卡 模拟银行卡app_i++

 自9时起199小时...