7779 - KKT基本算法304保龄球340
目录
- 题目
- 题解
- 思路
- 规则解析
- “奠基”
- 选择思路
- 读取数据
- 处理数据
- 完整代码
- 写在后面
题目
7779 - KKT基本算法304保龄球340 |
---|
难度级别:A; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B |
试题描述 |
保龄球游戏,打保龄球是用一个滚球去打击十个站立的柱,将柱击倒,一局分十轮,每轮可以滚球一次或两次,以击倒的柱数为依据计分,一局得分为十轮得分之和,而每轮的得分不仅与本轮的滚球情况有关,还可能与后续一两轮的滚球情况有关。即某轮某次滚球击倒的柱数不仅要计入本轮得分,还可能计入前一两轮的得分,具体的滚球计柱规则和计分方法如下: (1)某一轮的第一次滚球就击倒全部十个柱,则本轮不再滚球(若是第十轮,则还需另加两次滚球,不妨称其为第十一轮和第十二轮,并不是所有的情况都需要滚第十一轮和第十二轮),该轮得分为本次击倒的柱数10,与以后两次滚球所击倒的柱数之和。 (2)如某一轮的第一次滚球未击倒十个柱,则可对剩下未击倒的柱再滚一次。如果这两次滚球击倒全部十个柱,则本轮不再滚球(若是第十轮则还需另加一次滚球),该轮得分为这两次共击倒柱数10与以后一次滚球所击倒柱数之和。 (3)若某一轮两次滚球未击倒全部十个柱,则本轮不再继续滚球,该轮得分为这两次滚球击倒的柱数之和。总之,若某一轮中一次滚球或两次滚球击倒十个柱,则本轮得分是本轮首次滚球开始的连续三次滚球击倒柱数之和(其中有一次或两次不是本轮滚球)。若一轮内二次滚球击倒柱数不足十个,则本轮得分即为这两次击倒柱数之和。下面以实例说明如下: 见下方附表 现在请编写一个保龄球计分程序,用来计算并输出最后的总分。 |
输入 |
输入一行,为前若干轮的滚球结果,每轮滚球结果用一到两个字符表示,每一个字符表示一次击球,各轮结果之间用一个空格分隔。字符“/”表示击倒当前球道上的全部的柱,否则用一个数字字符表示本次滚球击倒的当前球道上的柱的数目,两轮滚球之间用一个空格隔开。 |
输出 |
输出一行一个整数,代表最后的得分。 |
输入示例 |
90 90 / 9/ 81 / / / 72 / / 0 |
输出示例 |
170 |
附表
轮 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
击球情况 | / | / | / | 72 | 9/ | 81 | 8/ | / | 9/ | / | 8/ | |
各轮得分 | 30 | 27 | 19 | 9 | 18 | 9 | 20 | 20 | 20 | 20 | ||
累计总分 | 30 | 57 | 76 | 85 | 103 | 112 | 132 | 152 | 172 | 192 |
题解
思路
注意这道题的题目有些难以理解,请务必看懂再自己做或读下去
规则解析
(1)我们管一次滚球就击中全部十个瓶叫做“全中”,记为“/”;而第二次滚球才击中全部十个瓶叫做“补中”,记为“(第一次击球数)/”,比如“3/”;如果两次都没有击中全部的球,则记为“(第一次击球数)(第二次击球数)”,比如“72”。
(2)比赛有十轮,每一轮有两次击球机会(非常重要,题目中的描述不太严谨,“第十一轮”“第十二轮”的称呼并不对)
(3)在每一轮中,若第一次击球便全中,本轮得分为本轮得分10+奖励分数(后两次击球所得的分);若补中,本轮得分为本轮得分10+奖励分数(后一次击球所得的分);若两次并没有击中全部的球,本轮得分为第一次击球数+第二次击球数。
(4)对题目难以理解的地方的特别解释:1.因为每一轮全中或补中都需要有奖励分数,因此第十轮(最后一轮)若全中,为了获得奖励分数需要再滚两次球(而不是两轮),若补中,为了获得奖励分数需要再滚一次球(而不是一轮)2.补中时,本轮得分(不含奖励分数)为10,而不是第一次击球数+“/”所代表的10。
“奠基”
往下看之前,请务必自己思考一下,看看有没有与文中不同的新思路。
在做这道题的时候,我以及我的同学主要用到以下方法:
1.使用课课通上的方法,将每一轮得分存入一个字符串(总共是一个字符串数组),通过字符串“.size()”的特性以及字符判断进行分数计算
2.将每轮得分存入表中,最后计算总分时对每轮分数求和
3.将全部得分存入一个字符数组中,用while循环以及数组下标还有无数if-else判断得分情况,并累计计算总分。
4.将全部得分存入一个字符数组中,设计函数1:可以计算字符数组中某一区间的分数,函数2:根据条件确定区间。在每一轮判断全中或补中或普通情况,若全中,则将区间从本轮向后扩展两个有效数值(两次滚球),若补中,则将区间从本轮向后拓展一个有效数值。
选择思路
最开始,我选择了思路3,但是因为这道题的数据有些奇怪,比如本应是“90 90 / 9/ 81 / / / 72 / / 0”却不知怎样少了个空格“90 90 / 9/ 81 / / / 72 / /0”,于是这种严格基于空格数计算下标的方法就泡汤了。
我百思不得其解,遂看同学代码,发现他使用了思路2,可惜我并不能读懂(因此对其解释最少),之后,我又尝试自己写出思路1的代码,可惜结果错误还是跃然于屏幕之上。
最终,我想到了思路4。本篇博客将主要讲解思路4。
读取数据
读取数据时,我们需要将整行包括空格原封不动地存入字符数组,显然cin>>等方法就失效了(它们遇到空格就会结束输入)。
于是我从同学那里学来了一个高超的技术:
int p=0;
while(scanf("%c",&score[p])!=EOF)p++;
也就是说,这种输入方法不撞EOF(文件末尾)便不停下,尤其适合我们的需求。
PS:我们在cmd窗口输入时需要按Ctrl + Z结束输入才会得到后续输出
处理数据
1.计算区间总分的函数
int calc(int f,int l)//f和l为区间的开头和结尾
{int res=0;//result = =for(int i=f;i<=l;i++){//首先我们跳过空格字符//"/"的ACSII码为47,减去'0'刚好的-1,,小于0,我们可以通过这个来判断if(score[i]!=' ')res+=score[i]-'0'<0?10:score[i]-'0';//这里用到了三目运算符,可以百度获得使用方法,当然平时不建议使用if(score[i]=='/' && score[i-1]!=' ' && i!=0)res=res-score[i-1]+'0';//这里是针对补中时也将“/”计算为10的bug的补丁,可能会有更好的方法}return res;
}
2.确定区间
int move(int f,int t)//f为区间开头,t为需要加入的滚球数
{while(score[f]!=' ')f++;//跳过本轮的得分,进入下一轮while(t)//当t!=0时,这里天然成立{f++;if(score[f]!=' ')t--;//多一次滚球我们就离目标更近一些}return f;
}
3.判断部分
while(rd<=10)
{if(score[i]=='/')sum+=calc(i,move(i,2)),i+=2;//若全中,则计算本轮和后两次滚球的得分计入总分 i+=2自动跳到下一轮else if(score[i+1]=='/')sum+=calc(i,move(i,1)),i+=3;//若补中,则计算本轮和后一次滚球的得分计入总分 i+=3自动跳到下一轮else sum+=calc(i,i+1),i+=3;//普通情况,则将两次击球数加起来计入总分 i+=3进入下一轮rd++;//只能打10轮啊
}
完整代码
#include<bits/stdc++.h>
using namespace std;
char score[101];
int move(int f,int t)
{while(score[f]!=' ')f++;while(t){f++;if(score[f]!=' ')t--;}return f;
}
int calc(int f,int l)
{int res=0;for(int i=f;i<=l;i++){if(score[i]!=' ')res+=score[i]-'0'<0?10:score[i]-'0';if(score[i]=='/' && score[i-1]!=' ' && i!=0)res=res-score[i-1]+'0';}return res;
}
int main()
{int i=0,p=0,sum=0,rd=1;while(scanf("%c",&score[p])!=EOF)p++;while(rd<=10){if(score[i]=='/')sum+=calc(i,move(i,2)),i+=2;else if(score[i+1]=='/')sum+=calc(i,move(i,1)),i+=3;else sum+=calc(i,i+1),i+=3;rd++;}cout<<sum;return 0;
}
写在后面
如果你能通过“90 90 / 9/ 81 / / / 72 / /0”(不使用针对样例的特判)(结果为170),那么你应该成功了
另外再次抱怨一下这题目描述= =浪费了我多少宝贵的时间
7779 - KKT基本算法304保龄球340相关推荐
- LeetCode算法日记:340.至多包含K个不同字符的最长子串
340.至多包含K个不同字符的最长子串 日期:2022/7/30 题目描述:给定一个字符串 *s* ,找出 至多 包含 k 个不同字符的最长子串 *T*. 示例: 输入: s = "eceb ...
- CK3M自定义伺服算法(C语言)开发的简单流程
本文的章节安排如下 1 注意事项 2 自定义伺服算法(C语言)开发 2.1 Global Includes 2.2 C Language 2.3 编译并下载程序 2.4 控制器调试 3 运动程序 在导 ...
- 论文阅读:Deep Learning in Mobile and Wireless Networking:A Survey
论文阅读:Deep Learning in Mobile and Wireless Networking:A Survey 从背景介绍到未来挑战,一文综述移动和无线网络深度学习研究 近来移动通信和 5 ...
- 编写python程序、计算账户余额_《计算机科学丛书PYTHON程序设计(原书第2版)/(美])凯.S.霍斯特曼》【价格 目录 书评 正版】_中国图书网...
出版者的话 译者序 前言 第1章 概述 1 1.1 计算机程序 1 1.2 深入剖析计算机 2 1.3 Python编程语言 4 1.4 熟悉编程环境 5 1.5 分析**个程序 9 1.6 错误 1 ...
- 浅谈人工智能与游戏思维
如何找到一种可产生意向性的形式化手段是通往人机有效融合的关键,目前的数学.物理手段还不具备完全承担这个重任的能力,因为这仅是智能--这个复杂性系统问题的两个方面而已. 下文首先 ...
- uos统一操作系统命令与linux一样,UOS统一操作系统仍然存在着不少的问题,需用户更新系统来完善...
UOS统一操作系统已经正式发布了,但是根据多人使用来看,UOS仍然存在着不少的问题,请用户不断的接收系统更新来完善.请先看统一桌面和服务器操作系统UOS 20正式版发布,附新特性/新特点介绍一文. 在 ...
- 【OR】二次规划(2):SCA方法
导航 前文链接 线性约束的非凸二次规划 SCA方法 算法框架 参考资料 前文链接 二次规划(1) 线性约束的非凸二次规划 QP问题 min12xTQx+cTxs.t.{aiT−bi≤0,i=1,-, ...
- 转帖 CSDN网友挑选的2007年最有价值文章-2010南非世界杯Vuvuzela
技术知识更新很快,而好的互联网内容散布各地,程序员如何快速整理.方便检索是一大需求,CSDN网摘服 务正是迎合这样的需求推出的服务,一年多来,得到很多网友的喜爱.同时,网友的参与和分享机制,让更多好的 ...
- Cocos2D-x权威指南
<Cocos2D-x权威指南> 基本信息 作者: 满硕泉 出版社:机械工业出版社 ISBN:9787111419136 上架时间:2013-4-15 出版日期:2013 年4月 开本:16 ...
最新文章
- 【计算机视觉】EmguCV学习笔记(2)图像的载入、显示和输出
- 会议室管理前端页面_福州会议室钟联系方式
- Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】
- EF mysql 数据迁移_EF Code First Migrations数据库迁移
- 13.4 常见的时期类和Math类
- maximum mean discrepancy
- PHP empty操作记录
- Class com.fasterxml.jackson.databind.ser.BasicSerializerFactory can not access a member of class com
- jq中的get()和eq()的区别
- idea运行java项目js中文乱码如何解决
- 高级火山图 突出显示自定义的基因volcanic volcano plot duqiang 差异基因火山图
- JS实现批量图片上传
- java面试宝典-抱你过岸
- 水比赛系列-HMI串口屏的使用
- 十大重要IT公司排名 -2009
- 高德地图加载谷歌地图瓦片
- 曾经是亚洲第一大学,如今靠野猪上热搜?这所985实在是太委屈了!!
- forest_train训练文件的生成代码
- JS封装数组API push,pop,shift,unshift,sort, reverse
- 旺旺文件上传服务器在哪,手机旺旺服务器在哪里设置