HNU程序设计训练——斯诺克台球

2023-10-17 03:59

本文主要是介绍HNU程序设计训练——斯诺克台球,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【问题描述】

斯诺克台球是一项古老而又时尚的运动,使用长方形球桌,台面四角以及两长边中心位置各有一个球袋,使用的球分为1个白球,15个红球和6个彩球共22个球。

其中母球(白球)1只,目标球21只。目标球中:红球15只各1分、黄球1只2分、绿球1只3分、咖啡球1只4分、蓝球1只5分、粉球1只6分、黑球1只7分。

djh.jpg

选手需要使用球杆撞击母球去击打目标球来完成得分,每局开始时总是先从红球开始。击球顺序为先打进红球(每次击打允许多个红球同时落袋),然后必须任意指定一个目标彩球击打,如果该彩球被打进(打进后需要再摆回),然后接着击打红球,直到红球全部落袋,然后以黄、绿、咖啡、蓝、粉红、黑的顺序逐个击球(不再摆回),最后以得分高者为胜。任何时候红球落袋都不再摆回,任何时候因犯规导致彩球落袋,彩球必须摆回。

斯诺克比赛由双方轮流击打,必须击打合规的目标球,打进则本方得到相应的分数并继续击打,未打进或犯规轮换为对方击打,未打进不得分,犯规将进行罚分处理。

犯规规则如下:

1.     当击打目标球时,如果先击打到或同时击打到一个或多个其他颜色的球,或者有其他颜色的球落袋,或者打空(未击打到任何球),则视为犯规。此时需要比较目标球的分值和与本犯规相关的其他颜色的球的分值,取其中最高的分值,如果该分值小于4,则对方加4分,否则对方加该分值。

2.     当击打红球落袋后,继续击打任意彩球时打空,即未打击到任何球,对方加4分。

相比正式的斯诺克比赛,本问题对规则进行了简化,任何时候都可以结束比赛并计算比赛结果,不考虑白球落袋的情况。

信息化时代的智能台球桌能自动记录实际比赛时的击打记录,并传送到后台,但该记录仅仅是流水记录,并且无参赛选手的任何信息,需要你编程计算每场比赛的比分,同时需要计算单杆100分及以上的情况(单杆得分是指选手一次连续击打所得分数之和)。

【输入形式】

输入第一行为正整数t (t≤100),表示有t组测试数据,每组数据代表一局比赛。

在输入中,球的颜色表示为:

               r-红色球 y-黄色球 g-绿色球 c-咖啡色球 b-蓝色球 p-粉红球 B-黑色球

接下来的每组数据包括若干行,每一行为一次击打的结果,为智能球桌记录下来的流水记录,每组数据最后一行为-1,表示每组数据的结束。

流水记录包含用空格分隔的2个部分:

首先撞到的球 落袋球及数量

第一部分“首先撞到的球”为一个字符串,可以是“rygcbpB”中1个或多个字符组合(可能有多个字符“r”),或为字符串“NULL”。为“NULL”时,第二部分必为空,表示该次击打未撞击到任何球也没有任何球落袋。当红球落袋后继续击打任意彩球时,该部分为“ygcbpB”中的任意单个字符时都认为是合规的目标球。

第二部分“落袋球及数量”为一个字符串,例如“r2gb”,代表本次击打有两个红球落袋,以及绿球和篮球落袋,红色球r后面有数字(大于0小于16),表示红球的落袋数,其他彩球后无数字。该部分可以为空,表示本次击打无球落袋。

比赛在A与B之间进行,每局比赛总是由A先开球。

【输出形式】

输出为t+1行,前t行每行输出用冒号分隔的两个整数,表示每局比赛A与B之间的比分;最后一行输出用冒号分隔的两个整数,表示t局比赛之后A与B之间获得的单杆100分及以上的次数之比(单杆得分是指选手一次连续击打所得分数之和)。

【样例输入】

3
r r1
B
r r2
c c
r r1
b g
-1
rp r1
r br2B
NULL
r r12
y y
g p
-1
rr r3
NULL
r r1
yg y
-1

【样例输出】

6:7

13:24

7:5

0:0

【样例说明】

第一局比赛:

A击打红球,打进1个红球,得1分,比分为 1:0

A继续击打任意彩球,打到黑球,未打进,不得分,比分为1:0

轮换为B击打红球,打进两个红球,得2分,比分为1:2

B继续击打任意彩球,打到咖啡球,打进咖啡球,咖啡球摆回,得4分,比分为1:6

B继续击打红球,打进一个红球,得1分,比分为1:7

B继续击打任意彩球,打到蓝球,打进绿球,犯规,取分值最大者蓝球,绿球摆回,对方加5分,比分为6:7

-1比赛结束

第二局比赛:

A击打红球,首先打到红球和粉球,犯规,打进1个红球和咖啡球,犯规,咖啡球摆回,取分值最大的粉球,对方加6分,比分为0:6

B击打红球,首先打到红球,打进蓝球、2个红球和黑球,犯规,蓝球和黑球摆回,取分值最大的黑球,对方加7分,比分为7:6

A击打红球,未打到任何球,犯规,对方加4分,比分为7:10

B击打红球,打到红球,打进12个红球,加12分,比分为7:22

B击打任意彩球,打到黄球,打进黄球,黄球摆回,得2分,比分为7:24

B击打黄球,打到绿球,打进粉球,犯规,粉球摆回,对方加6分,比分为13:24

-1比赛结束

第三局比赛:

A击打红球,打到2个红球,打进3个红球,加3分,比分为3:0

A击打任意彩球,打空,未打到任何球,对方加4分,比分为3:4

B击打红球,打到1个红球,打进1个红球,加1分,比分为3:5

B击打任意彩球,打到黄球和绿球,打进黄球,犯规,黄球摆回,取分值最高的绿球,绿球分值小于4,对方加4分,比分为7:5 

-1比赛结束

3局比赛中无人单杆得分过100,最后一行输出0:0

需要统计的变量和情况很多,很麻,特别麻

#include <iostream>
#include <string>
using namespace std;int suma = 0, sumb = 0;//单杆得分过100的次数
int runa = 0, runb = 0;//ab当前连续得分数
int scorea = 0, scoreb = 0;//ab单场比赛得分
int rsum = 0, ysum = 0, gsum = 0, csum = 0, bsum = 0, psum = 0, Bsum = 0;//统计球进袋数
int flag = 1;//奇数代表a的球权,偶数为b球权
int FLAG = 1;//FLAG为奇数表示击打规定球,FLAG为偶数表示可击打任意彩球
//转换同球对应的得分
int conver1(char c)
{if (c == 'r') return 1;else if (c == 'y') return 2;else if (c == 'g') return 3;else if (c == 'c') return 4;else if (c == 'b') return 5;else if (c == 'p') return 6;//else if (c == 'B')return 7;
}
//处理犯规函数foul
void foul(int flag, int sum)
{if (sum < 4) sum = 4;if (flag % 2)//a犯规scoreb += sum;elsescorea += sum;
}
//获取现在应该打什么球
char stipulate()
{if (rsum < 15) return 'r';else if (ysum == 0) return 'y';else if (gsum == 0) return 'g';else if (csum == 0) return 'c';else if (bsum == 0) return 'b';else if (psum == 0) return 'p';//else if (Bsum == 0) return 'B';
}
void goal(char c, int sum = 1)//c颜色的球进了sum颗(书名默认为1)
{if (c == 'r') rsum += sum;else if (c == 'y') ysum++;else if (c == 'g') gsum++;else if (c == 'c') csum++;else if (c == 'b') bsum++;else if (c == 'p') psum++;else if (c == 'B') Bsum++;
}
//主处理函数
void fun(string s)
{int space = s.find(' ');//寻找s中的空格,没有找到就是没进球int foulflag = 0;//纪录犯规球的最高分bool foulFLAG = true;//纪录是否犯规int reflag = false;//目标球是否打进int resum = 0;//没有犯规且进球了应加的分bool rsumflag = false;//在击打规定球的回合判断红球是不是在本回合全部打入袋中。如果是下回合已经可以击打任意彩球if (FLAG%2)//应击打规定球,当红球全落袋后每次都按顺序击球{char re = stipulate();//确定应击打的球if (space != -1){for (int i = 0; i < space; i++){if (s[i] != re)//打到非目标球就是犯规{foulflag = max(foulflag, conver1(s[i]));foulFLAG = false;}}//space后for (unsigned int i = space + 1; i < s.length(); i++){if (s[i] == re){reflag = true;//目标球打进了if (re == 'r'){while (s[++i] >= '0' && s[i] <= '9')resum = resum*10 + s[i] - '0';i--;goal(re, resum);if (rsum == 15)rsumflag = true;//红色球是在本次回合全部进袋,下次依旧可以选择任意球打}else{resum = conver1(re);goal(re);}}else//别的球进了,犯规{foulFLAG = false;if (s[i] == 'r'){int rrsum = 0;while (s[++i] >= '0' && s[i] <= '9')rrsum = rrsum*10 + s[i] - '0';i--;if (rsum == 15)rsumflag = true;//红色球是在本次回合全部进袋,下次依旧可以选择任意球打goal(re, rrsum);}//红球任何时候进了都不放回elsefoulflag = max(foulflag, conver1(s[i]));}}}else//没有进球{for (unsigned int i = 0; i < s.length(); i++){if (s[i] != re)//打到非目标球就是犯规{foulflag = max(foulflag, conver1(s[i]));foulFLAG = false;}}}}else//任意指定一个目标彩球击打{char re = s[0];//将第一个打到的球设为目标球foulflag = conver1(re);// 之后可能犯规,先将目标球设为犯规的最高分if (space != -1){for (int i = 1; i < space; i++){if (s[i] != re)//打到非目标球就是犯规{foulflag = max(foulflag, conver1(s[i]));foulFLAG = false;}}//space后for (unsigned int i = space + 1; i < s.length(); i++){if (s[i] == re){reflag = true;//目标球打进了if (re == 'r'){while (s[++i] >= '0' && s[i] <= '9')resum = resum*10 + s[i] - '0';i--;goal(re, resum);}else//不是打进的红球后续要拿出,无需统计进袋resum = conver1(re);}else//别的球进了,犯规{foulFLAG = false;if (s[i] == 'r'){int rrsum = 0;while (s[++i] >= '0' && s[i] <= '9')rrsum = rrsum*10 + s[i] - '0';i--;goal(re, rrsum);}//红球任何时候进了都不放回elsefoulflag = max(foulflag, conver1(s[i]));}}}else//没有进球{for (unsigned int i = 0; i < s.length(); i++){if (s[i] != re)//打到非目标球就是犯规{foulflag = max(foulflag, conver1(s[i]));foulFLAG = false;}}}}if (!foulFLAG)//犯规了foul(flag, foulflag);else if (reflag)//没有犯规且打进目标球{if (flag % 2)//a的球权scorea += resum, runa += resum;elsescoreb += resum, runb += resum;if (runa >= 100) suma++,runa=0;if (runb >= 100) sumb++,runb=0;//清零防止多次计算FLAG++;//改变下次应打的目标球}if (rsum == 15&&!rsumflag)FLAG = 1;//当红球全入袋且不是在本次指定击打红球时全部入袋后,每次都应击打规定球if (space == -1 || !foulFLAG){flag++;//未进球或者犯规了则交换球权runa = 0, runb = 0;//连续得分清0FLAG = 1;//交换球权后一个先打指定球}
}
//单场比赛前参数初始化
void initialize() 
{FLAG = 1;//FLAG为0表示击打规定球,FLAG为1表示可击打任意彩球flag = 1;//球权初始为Aruna = 0, runb = 0;//ab当前连续得分数scorea = 0, scoreb = 0;//ab单场比赛得分rsum = 0, ysum = 0, gsum = 0, csum = 0, bsum = 0, psum = 0, Bsum = 0;//统计球进袋数
}
int main()
{int t = 0;cin >> t;getchar();while (t--){initialize();string s;while (getline(cin, s), s != "-1"){if (s == "NULL")foul(flag++, 4);//flag++ 交换球权else{fun(s);}}cout << scorea << ':' << scoreb << endl;}cout << suma << ':' << sumb;return 0;
}

这篇关于HNU程序设计训练——斯诺克台球的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/222782

相关文章

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

Spark MLlib模型训练—聚类算法 PIC(Power Iteration Clustering)

Spark MLlib模型训练—聚类算法 PIC(Power Iteration Clustering) Power Iteration Clustering (PIC) 是一种基于图的聚类算法,用于在大规模数据集上进行高效的社区检测。PIC 算法的核心思想是通过迭代图的幂运算来发现数据中的潜在簇。该算法适用于处理大规模图数据,特别是在社交网络分析、推荐系统和生物信息学等领域具有广泛应用。Spa

SigLIP——采用sigmoid损失的图文预训练方式

SigLIP——采用sigmoid损失的图文预训练方式 FesianXu 20240825 at Wechat Search Team 前言 CLIP中的infoNCE损失是一种对比性损失,在SigLIP这个工作中,作者提出采用非对比性的sigmoid损失,能够更高效地进行图文预训练,本文进行介绍。如有谬误请见谅并联系指出,本文遵守CC 4.0 BY-SA版权协议,转载请联系作者并注

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录 在深度学习项目中,目标检测是一项重要的任务。本文将详细介绍如何使用Detectron2进行目标检测模型的复现训练,涵盖训练数据准备、训练命令、训练日志分析、训练指标以及训练输出目录的各个文件及其作用。特别地,我们将演示在训练过程中出现中断后,如何使用 resume 功能继续训练,并将我们复现的模型与Model Zoo中的

C语言程序设计(选择结构程序设计)

一、关系运算符和关系表达式 1.1关系运算符及其优先次序 ①<(小于) ②<=(小于或等于) ③>(大于) ④>=(大于或等于 ) ⑤==(等于) ⑥!=(不等于) 说明: 前4个优先级相同,后2个优先级相同,关系运算符的优先级低于算术运算符,关系运算符的优先级高于赋值运算符 1.2关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式,逻辑表达式,赋值表达式,字符

多云架构下大模型训练的存储稳定性探索

一、多云架构与大模型训练的融合 (一)多云架构的优势与挑战 多云架构为大模型训练带来了诸多优势。首先,资源灵活性显著提高,不同的云平台可以提供不同类型的计算资源和存储服务,满足大模型训练在不同阶段的需求。例如,某些云平台可能在 GPU 计算资源上具有优势,而另一些则在存储成本或性能上表现出色,企业可以根据实际情况进行选择和组合。其次,扩展性得以增强,当大模型的规模不断扩大时,单一云平

智能工厂程序设计 之1 智能工厂都本俱的方面(Facet,Aspect和Respect)即智能依赖的基底Substrate 之1

Q1、昨天分别给出了三个智能工厂的 “面face”(里面inter-face,外面outer-face和表面surface) 以及每个“面face” 各自使用的“方”(StringProcessor,CaseFilter和ModeAdapter)  。今天我们将继续说说三个智能工厂的“方面” 。在展开之前先看一下三个单词:面向facing,取向oriented,朝向toword。理解这三个词 和

神经网络训练不起来怎么办(零)| General Guidance

摘要:模型性能不理想时,如何判断 Model Bias, Optimization, Overfitting 等问题,并以此着手优化模型。在这个分析过程中,我们可以对Function Set,模型弹性有直观的理解。关键词:模型性能,Model Bias, Optimization, Overfitting。 零,领域背景 如果我们的模型表现较差,那么我们往往需要根据 Training l