当前位置: 首页 > news >正文

以游戏编程的角度看待模拟时间的算法题——以PAT甲级1026 Table Tennis为例

对于需要模拟时间的算法题,可以将开始时间作为游戏的开始(如Unity的Start或UE的BeginPlay),每一秒的模拟作为游戏的画面更新(如Unity的Update或UE的Tick),结束时间可作为游戏的结束(如Unity的OnDestroy或UE的EndPlay)。

从这个角度来看,我们可以将PAT甲级1026 Table Tennis当成一个游戏看待,在游戏进行过程中,游戏玩家可能随时会让一位球员来打球。因此可以将可能到来的球员当成玩家输入来处理。

在每个时刻(每一秒),我们读取玩家输入,然后按照指定的游戏玩法(题目的规则)来进行游戏数据的更新。

对于游戏玩法,其要点如下:

  • 球员可能是VIP球员也可能是一个普通球员;
  • VIP球员唯一享有的特权就是当有空闲的VIP球桌,他可以上VIP球桌打球。(这意味着:如果没有空闲的VIP球桌,VIP球员就是普通球员;如果没有VIP球员在等待打球,那么VIP球桌就是普通球桌。……看似很复杂,其实不影响游戏逻辑。)

因此按照第二点玩法我们可以给出游戏在每一秒的逻辑:

  1. 获取玩家输入,获得该时刻到来的球员(题目说每秒只会到来一个球员),将其加入球员等待队列,对于VIP球员,将其额外加入VIP球员等待队列。
  2. 遍历每一个VIP球桌,按照VIP球员到来的顺序让其上球桌打球
  3. 遍历每一个球桌,按照球员到来的顺序让其上球桌打球
#include<bits/stdc++.h>
using namespace std;const int kOpenTime  = 8 * 60 * 60;  // 开门时间 8点
const int kCloseTime = 21 * 60 * 60; // 关门时间 21点// 玩家类
struct Player {int  arrvTime; // 球员到达时间int  playTime; // 球员占用球桌的时间int  waitTime; // 球员等待时间bool isVip;// 球员是不是vipint  num;      // 球员的输出的编号static const int kInvalidNum = 0xffffff;Player(): arrvTime(kOpenTime), playTime(0), waitTime(0), isVip(false), num(kInvalidNum) {}[[nodiscard]] bool isPlayed() const { return num !=  kInvalidNum; };
};// 球桌类
struct Table {int  endTime;  // 上一对球员打完球离开该球桌的时间int  id;bool isVip;// 是不是vip桌int  serveNum; // 桌子招待过多少球员Table(): id{-1}, endTime(kOpenTime), isVip(false), serveNum(0) {}[[nodiscard]] bool isFree(int nowTime) const { return endTime <= nowTime; }
};// 游戏场景中某个对象所挂载的脚本类
class TableTennisManager
{
private:vector<Player>  m_players;// 下面两个queue内存储的是m_players内元素的指针queue<Player *> playersWaitQueue;queue<Player *> vipPlayersWaitQueue;int m_unarrivedIDBegin = 0;int m_playedCnt = 0; // 记录球员上桌的顺序vector<Table *> m_tables_VIP;vector<Table *> m_tables;// 将每个时刻到来的球员当做一个输入,将该球员放入队列中让HandleQueue来处理void HandleInput(int nowTime) {for(int playerID = m_unarrivedIDBegin; playerID < m_players.size(); playerID++) {Player & player = m_players[playerID];if(player.arrvTime <= nowTime) {m_unarrivedIDBegin++;playersWaitQueue.emplace(&player);if(player.isVip)vipPlayersWaitQueue.emplace(&player);} else {break;}}}void HandleQueue(int nowTime, vector<Table *> & tables, queue<Player *> & waitPlayers){// 清除已处理过的球员while(!waitPlayers.empty()) {if(waitPlayers.front()->isPlayed()) {waitPlayers.pop();} else {break;}}for(auto table: tables) {if(!table->isFree(nowTime))continue;if(waitPlayers.empty())break;/* 该桌空闲,让正在等待的球员上桌 */// 弹出等待队列,处理该球员Player * player = waitPlayers.front();waitPlayers.pop();// 更新球员数据player->waitTime = nowTime - player->arrvTime;player->num = m_playedCnt++;// 更新球桌数据table->endTime = nowTime + player->playTime;table->serveNum++;}}public:/// 游戏开始,接收游戏过程中可能需要的数据输入,模拟玩家输入并构造游戏场景————在第一次调用Update前调用// m_players模拟玩家输入,m_tables是游戏场景所需的游戏对象void Begin(){int nPlayers, nTables, nVipTables; // 球员对的数量、球桌数、VIP球桌数// 输入在营业时间内到达的球员数据cin >> nPlayers;m_players.resize(nPlayers);int nPlayers_real = 0; // 记录符合要求的输入数据(到达时间在21点之前的球员)for(int i = 0; i < nPlayers; ++i) {// 输入:每队球员的到达时间、占用球桌的时间(最多不能超过两小时)、是否是VIPint h, m, s, playT, isVip;scanf("%d:%d:%d %d %d\n", &h, &m, &s, &playT, &isVip); //NOLINTint arvT = (h*60 + m)*60 + s; // 按照秒数记录player到达时间// 只保留在关门前到达的球员if(arvT < kCloseTime){Player player;player.arrvTime = arvT;player.playTime = playT > 120 ? 120 * 60 : playT * 60; // 打球超过2小时的都要强制变成120分钟player.isVip = isVip;m_players[nPlayers_real++] = player;}}m_players.resize(nPlayers_real);// 输入球桌数据cin >> nTables >> nVipTables;m_tables.resize(nTables);for(int i = 0; i < nTables ; i++) {m_tables[i] = new Table{};}// 输入VIP球桌数据for(int i = 0; i < nVipTables; ++i) {int tableID;cin >> tableID;tableID--;m_tables[tableID]->isVip = true; // 标记vip桌m_tables[tableID]->id = tableID;m_tables_VIP.push_back(m_tables[tableID]);}// 按照球员到达时间排序sort(m_players.begin(), m_players.end(), [](Player &a, Player &b){return a.arrvTime < b.arrvTime;});}/// 更新游戏数据,更新游戏场景数据(m_players和m_tables)————每个时刻(每秒)调用一次void Update(int nowTime){// 处理该时刻可能到达的球员HandleInput(nowTime);// 在VIP球桌上处理VIP球员HandleQueue(nowTime, m_tables_VIP, vipPlayersWaitQueue);// 在所有球桌上处理所有球员(上一步因为VIP球桌已满而未能进入VIP球桌的VIP球员将会被视为普通球员处理)HandleQueue(nowTime, m_tables, playersWaitQueue);}/// 游戏结束,输出游戏执行结果————在最后一次Update执行完调用void End(){// 将球员按照打球的顺序进行排序sort(m_players.begin(), m_players.end(), [](Player &a, Player &b){return a.num < b.num;});// 输出球员的打球信息for(Player &player: m_players) {if(player.num == 0xffffff) continue; // 超过21点才能打球的球员就不能输出了int ah = player.arrvTime/3600, am = player.arrvTime % 3600 / 60, as = player.arrvTime % 60;int bh = (player.arrvTime + player.waitTime) / 3600, bm = (player.arrvTime + player.waitTime) % 3600 / 60, bs = (player.arrvTime + player.waitTime) % 60;// 等待的分钟数要四舍五入player.waitTime = player.waitTime/60 + (player.waitTime%60 >= 30);printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",ah,am,as,bh,bm,bs,player.waitTime);}// 输出球桌的接待信息for(int i = 0; i < m_tables.size(); ++i) {cout << m_tables[i]->serveNum << (i == m_tables.size() - 1 ? "\n" : " ");delete m_tables[i];}}
};int main() {TableTennisManager tennisManager;tennisManager.Begin();for (int nowTime = kOpenTime; nowTime < kCloseTime; nowTime++) {// 每秒调用一次,对相关数据进行更新tennisManager.Update(nowTime);}tennisManager.End();return 0;
}

相关文章:

以游戏编程的角度看待模拟时间的算法题——以PAT甲级1026 Table Tennis为例

对于需要模拟时间的算法题&#xff0c;可以将开始时间作为游戏的开始&#xff08;如Unity的Start或UE的BeginPlay&#xff09;&#xff0c;每一秒的模拟作为游戏的画面更新&#xff08;如Unity的Update或UE的Tick&#xff09;&#xff0c;结束时间可作为游戏的结束&#xff08;…...

SNAT与DNAT原理

SNAT和DNAT &#xff08;源地址转换和目标地址转换&#xff09; SNAT&#xff1a;源地址转换。内网到外网转换的是源地址。 DNAT&#xff1a;目标地址转换&#xff1a;外网到内网转换的是目的地址 &#xff08;把内部服务器的ip地址转换成一个所有人都可以访问的地址&#xff0…...

04-2_Qt 5.9 C++开发指南_SpinBox使用

文章目录 1. SpinBox简介2. SpinBox使用2.1 可视化UI设计2.2 widget.h2.3 widget.cpp 1. SpinBox简介 QSpinBox 用于整数的显示和输入&#xff0c;一般显示十进制数&#xff0c;也可以显示二进制、十六进制的数&#xff0c;而且可以在显示框中增加前缀或后缀。 QDoubleSpinBox…...

接口安全防护方案

文章目录 1.认证与授权机制2.参数校验3.接口加密4.防止暴力破解5.安全头设置6.日志监控 1.认证与授权机制 使用令牌&#xff08;Token&#xff09;、OAuth等认证方式&#xff0c;确保只有合法用户可以访问接口。授权机制可以防止未经授权的用户访问敏感接口。 示例&#xff1a;…...

机器学习复习题

1 单选题 ID3算法、C4.5算法、CART算法都是&#xff08; &#xff09;研究方向的算法。 A . 决策树 B. 随机森林 C. 人工神经网络 D. 贝叶斯学习 参考答案&#xff1a;A &#xff08; &#xff09;作为机器学习重要算法之一&#xff0c;是一种利用多个树分类器进行分类和预测…...

无线液位传感器—简介

近年来&#xff0c;随着无线传感网络技术的愈发成熟和稳定&#xff0c;无线传感器因其安装、维护方便&#xff0c;不用布线、节约成本&#xff0c;监测方便&#xff0c;使用灵活&#xff0c;可适用于多种工业领域等优点&#xff0c;正在逐步替代部分传统有线传感器&#xff0c;…...

通讯协议034——全网独有的OPC HDA知识一之聚合(三)时间加权平均

本文简单介绍OPC HDA规范的基本概念&#xff0c;更多通信资源请登录网信智汇(wangxinzhihui.com)。 本节旨在详细说明HDA聚合的要求和性能。其目的是使HDA聚合标准化&#xff0c;以便HDA客户端能够可靠地预测聚合计算的结果并理解其含义。如果用户需要聚合中的自定义功能&…...

Android 13 Hotseat定制化修改——003 hotseat图标大小修改

目录 一.背景 二.未修改前效果 三.修改后效果 一.背景 由于需求是需要自定义修改Hotseat,所以此篇文章是记录如何自定义修改hotseat的,应该可以覆盖大部分场景,修改点有修改hotseat布局方向,hotseat图标数量,hotseat图标大小,hotseat布局位置,hotseat图标禁止形成文件…...

21、springboot的宽松绑定及属性处理类的构造注入

springboot的宽松绑定及属性处理类的构造注入 ★ 如何使用属性处理类所读取的属性 属性处理类最终变成了Spring容器中的一个Bean组件&#xff0c;因此接下来Spring即可将该Bean组件注入任意其他组件。 这种做法的好处是&#xff1a;可以将大量的配置信息封装一个对象——所以…...

nginx负载均衡(反向代理)

nginx负载均衡 负载均衡&#xff1a;由反向代理来实现。 nginx的七层代理和四层代理&#xff1a; 七层是最常用的反向代理方式&#xff0c;只能配置在nginx配置文件的http模块当中&#xff0c;而且配置方法名称&#xff1a;upstream模块&#xff0c;不能写在server模块中&#…...

AWS上传私有windows server2019镜像64位

一.制作自己的镜像 我使用的是esxi&#xff0c;建立一个windows虚拟机&#xff0c;开启。 根据aws官方文档&#xff0c;虚拟机里的系统重要需要注意以下几点&#xff1a; 1.只有一张网卡&#xff0c;ip获取配置成dhcp。 2.关闭系统防火墙。 3.开启windows rdp 远程功能。 …...

查看当前仓库对应的远程仓库地址

查看当前仓库对应的远程仓库地址 git remote -v这条命令能显示你当前仓库中已经添加了的仓库名和对应的仓库地址&#xff0c;通常来讲&#xff0c;会有两条一模一样的记录&#xff0c;分别是fetch和push&#xff0c;其中fetch是用来从远程同步 push是用来推送到远程 修改仓库…...

flask-script

# django中&#xff0c;有命令 python manage.py runserver python manage.py makemigrations ...自定制命令&#xff08;django如何自定制命令&#xff09;... -python manage.py init_db excel文件路径 指定表名 # flask启动项目&#xff0c;像djag…...

标准的OSI七层模型(其实了解tcp足矣)

七层模型&#xff0c;亦称OSI&#xff08;Open System Interconnection&#xff09;。参考模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间互联的标准体系&#xff0c;一般称为OSI参考模型或七层模型。 它是一个七层的、抽象的模型体&#x…...

【C++】初识模板

C模板入门 一、泛型编程 二、函数模板1. 函数模板的概念2. 函数模板格式3. 函数模板的原理4. 函数模板的实例化5. 模板参数的匹配原则 三、类模板 一、泛型编程 假设我们想实现一个交换函数&#xff0c;并且支持不同类型的参数实现&#xff0c;我们可以用 typedef 将类型进行重…...

学习Pull request

我从我的导师Xing Fan指导和帮助&#xff0c;利用我的导师chunlong Li提供ChatGPT&#xff0c;在百度搜索&#xff0c;学习一些资料。以下很多内容都是我的导师Xing Fan做的。谢谢Xing Fan。考虑到隐私&#xff0c;不适合截图公开。 第一步&#xff1a; 打开Git Bash Here 如…...

python爬虫实战(1)--爬取新闻数据

想要每天看到新闻数据又不想占用太多时间去整理&#xff0c;萌生自己抓取新闻网站的想法。 1. 准备工作 使用python语言可以快速实现&#xff0c;调用BeautifulSoup包里面的方法 安装BeautifulSoup pip install BeautifulSoup完成以后引入项目 2. 开发 定义请求头&#xf…...

React Hooks 详细使用介绍

useState 状态管理 useState 是 React 中的一个基础 Hook&#xff0c;允许你在不使用 class 组件的情况下管理组件状态。 参数 初始值 你可以直接传递状态的初始值给 useState&#xff1a; const [name, setName] useState("John");使用函数设置初始值 当初始…...

python版《羊了个羊》游戏开发第一天

Python小型项目实战教学课《羊了个羊》 一、项目开发大纲&#xff08;初级&#xff09; 版本1.0&#xff1a;基本开发 课次 内容 技术 第一天 基本游戏地图数据 面向过程 第二天 鼠标点击和移动 面向对象 第三天 消除 设计模式&#xff1a;单例模式 第四天 完整…...

【uniapp】原生子窗体subNvue的使用与踩坑

需求 最近接到个需求, 需要在video组件上弹出弹窗, 也就是覆盖video这个原生组件 未播放时, 弹窗可以覆盖, 但是当video播放时, 写的弹窗就覆盖不了了 因为video是原生组件, 层级非常高, 普通标签是覆盖不了的, map标签同理 覆盖原生组件, 官方给出解决办法一. 使用cover-view…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

【Java】Ajax 技术详解

文章目录 1. Filter 过滤器1.1 Filter 概述1.2 Filter 快速入门开发步骤:1.3 Filter 执行流程1.4 Filter 拦截路径配置1.5 过滤器链2. Listener 监听器2.1 Listener 概述2.2 ServletContextListener3. Ajax 技术3.1 Ajax 概述3.2 Ajax 快速入门服务端实现:客户端实现:4. Axi…...

iOS 项目怎么构建稳定性保障机制?一次系统性防错经验分享(含 KeyMob 工具应用)

崩溃、内存飙升、后台任务未释放、页面卡顿、日志丢失——稳定性问题&#xff0c;不一定会立刻崩&#xff0c;但一旦积累&#xff0c;就是“上线后救不回来的代价”。 稳定性保障不是某个工具的功能&#xff0c;而是一套贯穿开发、测试、上线全流程的“观测分析防范”机制。 …...

SFTrack:面向警务无人机的自适应多目标跟踪算法——突破小尺度高速运动目标的追踪瓶颈

【导读】 本文针对无人机&#xff08;UAV&#xff09;视频中目标尺寸小、运动快导致的多目标跟踪难题&#xff0c;提出一种更简单高效的方法。核心创新在于从低置信度检测启动跟踪&#xff08;贴合无人机场景特性&#xff09;&#xff0c;并改进传统外观匹配算法以关联此类检测…...