我是靠谱客的博主 怕孤单乌冬面,最近开发中收集的这篇文章主要介绍斯诺克台球,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

斯诺克台球

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

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

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

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

犯规规则如下:

  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

AC代码


#include <iostream>
#include <tuple>
#include <sstream>
#include <vector>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cassert>
#include <cstdio>
#include <queue>
#include <set>
#include <map>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cstring>
#include <algorithm>
#include <numeric>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define mem0(a) memset(a, 0, sizeof(a))
#define lbs(v, x) lower_bound(all(v), x) - (v).begin()
#define ubs(v, x) upper_bound(all(v), x) - (v).begin()
#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); ++i)
#define per(i, a, n) for (int i= (int)(n) - 1; i >= (int)(a); --i)
#define for0(i, n) for (int i = 0; i < (int)(n); ++i)
#define for1(i, n) for (int i = 1; i <= (int)(n); ++i)
#define forn(i, a, n) for (int i = (int)(a); i <= (int)(n); ++i)
typedef long long i64;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<vi> vvi;
typedef vector<pii> vpii;
typedef double db;
const i64 md = 1000000007;
i64 mypow(i64 a, i64 e) {return e ? (e&1 ? mypow(a,e-1)*a%md : mypow(a*a%md,e>>1)) : 1;}
i64 gcd(i64 a, i64 b) {return b ? gcd(b, a%b) : a;}
template<class T>
inline void read(T& x) {
x=0;int f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x=x*f;
}
using namespace std;
map<char,int> m;
char caiqiusx[6]={'y','g','c','b','p','B'};nt n1,t[2]={0},h=15;
int flag=0,flag_qs=0,flagts=0;
string::size_type p;
string temp1,temp2;
string sq="ygcbpB";
int total[2]={0};
int l1=0;
int pd100()
{
if(l1>=100)
{
l1=0;return 1;
}
else
{
l1=0;return 0;
}
}
void fa1(string s1,string s2)
t[flag]+=pd100();
int it=4;
for(int i=0;i<s1.length();i++)
if(m[s1[i]]>it)
it=m[s1[i]];
for(int i=0;i<s2.length();i++)
if(m[s2[i]]>it)
it=m[s2[i]];
if(flag==0)
total[1]+=it;
else
total[0]+=it;
return ;
}
void fa2()
{
t[flag]+=pd100();
int it=4;//固定是4分。
if(flag==0)
total[1]+=it;
else
total[0]+=it;
return ;
}
int hongqiujian()
{
p=temp2.find('r');
string temp3="";
int temp=0;
if(p!=temp2.npos)//不论是否犯规,红球不放回。
{
for(int i=p+1;i<temp2.length();i++)
if(temp2[i]>='0'&&temp2[i]<='9')//如果是数字就加入temp3.
temp3+=temp2[i];
else break;// 如果碰到了其他字符则红球个数计入完。
temp+=atoi(temp3.c_str());//红球数。
h-=atoi(temp3.c_str());//剩余红球数减少。
}
return temp;
}
void hongqiu(string s1,string s2)
{
if(s1=="NULL")//这种特殊情况先判断。
{
fa1(s1,s2);return;//这里是偷懒了,由于必定是四分。
}
else if(s1.length()==1)//先对s1进行区分,此处是首先击打到的球只有一个;
{
int temp=0;//暂时存储一下打入的红球数,如果没有犯规就能用
temp=hongqiujian();//无论犯规与否,都要减少。
if(s1[0]=='r')//此球为红球。
{
if(s2=="")//1.此情况是:击打到了红球,但没有进。(不犯规)。
{
t[flag]+=pd100();
return ;
}
else//打进球了
{
p=temp2.find('r');
int flag2=0;//判断是否有彩球。
for(int i=0;i<sq.length();i++)
if(temp2.find(sq[i])!=temp2.npos)//在打入的球中找是否有彩球。没找到的跳过。
{
flag2=1;break;//此时犯规。
}
if(flag2==1)//犯规的结果
{
fa1(temp1,temp2);//犯了规则一。
return ;
}
else//没有彩球,而temp2又不为空。
{
total[flag]+=temp;flag--;flag_qs=1;l1+=temp;//此时由于没犯规,则flag--,这个player继续打。打彩球。
return ;
}
}
}
else//此时打入的不是红球。已经犯规了。
{
int temp;//红球数。
temp=hongqiujian();//无论犯规与否,都要减少。
fa1(s1,s2);//犯规一。
return ;
}
}
else//此处是首先击打到的球不只有一个;这里可能犯规了。
{
int temp=0,flag2=0;//暂时存储一下打入的红球数,如果没有犯规就能用
temp=hongqiujian();//无论犯规与否,都要减少。
for(int i=0;i<sq.length();i++)
if(temp1.find(sq[i])!=temp2.npos)//在打入的球中找是否有彩球。没找到的跳过。
{
flag2=1;break;//此时犯规。
}
if(flag2==1)//犯规的结果
{
fa1(temp1,temp2);//犯了规则一。
return ;
}
else//可知s1中都是r
{
if(s2=="")//1.此情况是:击打到了红球,但没有进。(不犯规)。
{
t[flag]+=pd100();
return ;
}
else//打进球了
{
p=temp2.find('r');
flag2=0;//判断是否有彩球。
for(int i=0;i<sq.length();i++)
if(temp2.find(sq[i])!=temp2.npos)//在打入的球中找是否有彩球。没找到的跳过。
{
flag2=1;break;//此时犯规。
}
if(flag2==1)//犯规的结果
{
fa1(temp1,temp2);//犯了规则一。
return ;
}
else//没有彩球,而temp2又不为空。
{
total[flag]+=temp;flag--;flag_qs=1;l1+=temp;//此时由于没犯规,则flag--,这个player继续打。打彩球。
return ;
}
}
}
}
return ;
}
void caiqiu(string s1,string s2)
{
if(h==0)//奖励球.最后打红球时未犯规,导致红球打完。
flagts=1;
else
flag_qs=0;//犯规是对方打红球,不犯规是自己打红球。
if(s1=="NULL")//此时犯规二
{
fa2();//由于打彩球时,打空了。
return ;
}
hongqiujian();//无论犯规与否,都要减少。
if(s1.length()==1)//先对s1进行区分,此处是首先击打到的球只有一个;
{
if(s1[0]=='r')//此时是犯规了;
{
fa1(s1,s2);//犯规一。
return ;
}
else//此时打击的不是红球没有犯规。
{
if(temp2=="")//此时没有打进球,故不得分。
{
t[flag]+=pd100();//此时也没有得分。单杆结束。
return ;
}
else//打进球了,然后分打进目标,还是打进其他。
{
if(temp2.length()==1)//打进了一个球。
{
if(temp2==temp1)//打进的是目标球。
{
total[flag]+=m[temp1[0]];flag--;l1+=m[temp1[0]];//合法得分。
return ;
}
else//打的不是目标球。此时已经犯规。
{
fa1(s1,s2);return ;//犯规一。
}
}
else//打进的不止一个球。必定犯规。
{
fa1(s1,s2);return ;//犯规一。
}
}
}
}
else//打到的不止一个。必定犯规。
{
fa1(s1,s2);return;//犯规一。不管是否打进。
}
return ;
}
int i1=0;
void finalqiu(string s1,string s2)//此时已进入最终阶段,不管红球了。
{
if(s1=="NULL")//此时犯规二
{
fa1(s1,s2);//由于打彩球时,打空了。
return ;
}
if(s1.length()==1)//先对s1进行区分,此处是首先击打到的球只有一个;
{
if(s1[0]==caiqiusx[i1])//打击的是按循序的。
{
if(s2=="")//此时没有打进,没有犯规,但也没有得分;
{
t[flag]+=pd100();//此时也没有得分。单杆结束。
return ;
}
else//打进球了
{
if(s2.length()==1)//打进一个球。
{
if(s1[0]==s2[0])//打的是目标球。
{
l1+=m[s1[0]];//单杆得分。
total[flag]+= m[s1[0]];//选手得分。
i1++;flag--;
return;
}
else//打的不是目标球。犯规一。
{
fa1(s1,s2);return ;
}
}
else//打进的不止一个,犯规。
{
fa1(s1,s2);return ;
}
}
}
else//目标球打错。犯规一。
{
fa1(s1,s2);return ;
}
}
else//打到的不止一个。必定犯规。
{
fa1(s1,s2);return;//犯规一。不管是否打进。
}
if(i1==6)
{
t[flag]+=pd100();//最终打完了;
return ;
}
return ;
}
int main()
{
m['r']=1;m['y']=2;m['g']=3;m['c']=4;m['b']=5;m['p']=6;m['B']=7;//先在map中储存一下,方便找。
cin>>n1;cin.get();
while(n1--)
{
i1=0;total[0]=0;total[1]=0;flag=0;flagts=0;flag_qs=0;h=15;//每局重置变量。
while(1)
{
//cout<<total[1]<<":"<<total[0]<<endl;
flag++;flag%=2;//交换player,如果不变,请在上一个情况flag--;
string s;getline(cin,s);
if(s=="-1")
break;
temp1="";temp2="";//重置 temp1.首先撞到的球和temp2.落袋球及数量
p=s.find(' ');//找寻s中是否有' '(空格)--有就说明有temp2;
if(p!=s.npos)//如果有空格
{
temp1=s.substr(0,p);//s中前一段分割给temp1,
temp2=s.substr(p+1);//后一格分割给temp2
}
else
{
temp1=s;//此时为"NULL",s2为"".
}
if(h==0)//在打球前判断两个标记该往哪去。
{
if(flag_qs==0)//这里将犯规后红球打完的情况统了一下。
{
flagts=1;
}
}
if(flagts==1&&h==0)//此时最终阶段,依次打彩球。红球为0.
finalqiu(temp1,temp2);
else if(flag_qs==0&&flagts==0)//此时要击打红球。必须有红球可打才行。//另一种情况。指向打完红球。
hongqiu(temp1,temp2);
else if(flag_qs==1&&flagts==0)//此时要击打彩球。此时必须剩下红球。
caiqiu(temp1,temp2);
}
t[flag]+=pd100();//全部打完,清杆 (这是计单杆过百的另一种情况,还有一种是犯规)。
cout<<total[1]<<":"<<total[0]<<endl;
}
cout<<t[1]<<":"<<t[0]<<endl;
return 0;
}

最后

以上就是怕孤单乌冬面为你收集整理的斯诺克台球的全部内容,希望文章能够帮你解决斯诺克台球所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部