URAL 2078 Bowling game

本文详细解析了一种保龄球比赛计分规则,并通过具体示例介绍了如何计算比赛中的最低分和最高分。同时,文章还提供了一段C++代码实现,帮助读者更好地理解和应用这些规则。

阅读理解题,超级难懂

就是说一个人去打保龄球,有10个回合,然后每个回合是有2个球打的,叫我们算出能得的最低分和最高分。

我大概翻译下

  1.  The game includes 10 frames (rounds), in each frame one can earn up to 30 points. 一场比赛,有10个回合
  2. In each frame, excluding the last one, the aim is to knock down 10 pins with two rolls. If all pins are knocked down with the first roll, the second roll is omitted. 。在前9场比赛中,有10个pin可以让我们打倒,一个回合有两个球,如果你用了一个球就把这些全部打到了,那么第二个球就忽略掉,这个要记住,因为后面的subscuence要用
  3. In the last frame one must initially knock down 10 pins with two rolls as well. If the player succeeds, (s)he gets an extra (third) roll. All available rolls must be used, that is, if all pins have been knocked down and there are rolls left, new 10 pins are put. These 10 pins, if knocked down, do not give extra rolls. 最后一个回合的时候,如果你用了两个球就把10个全部打到,那么你就会再进行一个回合,增加10个pins和一个保龄球给你,让你打,看看你能打多少分。如果你用了1个球就打到了10个的话,你后来就是有2个球,去打。这个地方是最坑了,要特判最后一个打到了多少,>20的情况有点复杂。
  4. If a strike is made (all pins knocked down with one roll) in each frame excluding the last one, the player receives one extra point per each pin knocked down in two subsequent rolls when scoring that frame.
  5. If a spare is made (all pins knocked down with two rolls) in each frame excluding the last one, the player receives one extra point per each pin knocked down in one subsequent roll when scoring that frame. 就是说如果你用一个球就打倒了10个的话,你后来的连续两个球积分加倍,(第二个球是忽略掉的,不算在里面)。如果你用了2个球打倒10个的话,你后来的一个球积分加倍。

 

  好了,现在先求最小值,很容易,我每次都认为它是最后才打到a[i]个球的,那么值是最小的。也就是,它不是一个回合有两个球吗?你每次都认为它是第二个球打倒的,这样是最小的,为什么呢?因为它不会受10加倍的影响,比如我是第一个回合,打到了10个,我认为它是0、10这样打到的,然后后一个积分加倍,后一个打到8吧,你认为它是0、8这样打到的,积分加倍失效,所以这样是最小的。同理,最大的时候是8、0这样打。10、0的话,后面的那个0省略了。

然后坑爹出现了。

最后一场,它给的是你一共打到了多少个pins,如果你打到了20个以上,你只能是10、10、val[i]-20这样打的,所以这样和以前的积分加倍规则有点不同。如果打到20个一下,你算最小的时候,还是可以不受前面的积分加倍影响的,因为你可以看成是0、10、val[i]-10这样打。。依次类推吧。

代码写的很乱,坑爹情况已经给出来了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
typedef unsigned long long int ULL;
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 200;
int add[maxn];
int val[maxn];
void work ()
{
    int mi=0,mx=0;
    int t=0;
    for (int i=1;i<=10;++i)
    {
        int x;
        scanf("%d",&x);
        if (i != 10) mi += x;
        val[++t]=x;
        val[++t]=0;
    }
    for (int i=1;i<=t-2;++i)
    {
        if (val[i]==10)
        {
            add[i+2]++;
            if (val[i+2]==10)
            {
                add[i+2+2]++;
            }
            else add[i+2+1]++;
        }
    }

    for (int i=1;i<=t-2;++i)
    {
        mx += val[i] + val[i]*add[i];
    }

    if (val[19]<=10)
    {
        mi += val[19];
        mx += val[19] + val[19]*add[19];
        printf ("%d %d\n",mi,mx);
        return ;
    }
    if (val[17] != 10) //没有对最后一场影响
    {
        mi += val[19];
        mx += val[19];
        printf ("%d %d\n",mi,mx);
        return ;
    }
    else //you yingxiang
    {
        if (val[19]<=20)
        {
            mi += val[19];
            mx += 10 + add[19]*10  + (val[19]-10) + (val[19]-10)*add[20];
            printf ("%d %d\n",mi,mx);
            return ;
        }
        else //  >=21
        {
            mi += 20+val[19]-10;
            mx += 10+10*add[19] + 10 + 10*add[20] + val[19]-20;
            printf ("%d %d\n",mi,mx);
        }
    }
    return ;
}
int main()
{
#ifdef LOCAL
    freopen("data.txt","r",stdin);
#endif
    work();
    return 0;
}
View Code

例子:

10 10 1 1 1 1 1 1 1 19

10 10 1 1 1 1 1 1 1 21

10 10 1 1 1 1 1 1 1 10

转载于:https://www.cnblogs.com/liuweimingcprogram/p/5804659.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值