Darts

In the game of darts a player throws three darts at a target board which is split into twenty equal sized sections numbered one to twenty.

The score of a dart is determined by the number of the region that the dart lands in. A dart landing outside the red/green outer ring scores zero. The black and cream regions inside this ring represent single scores. However, the red/green outer ring and middle ring score double and treble scores respectively.

At the centre of the board are two concentric circles called the bull region, or bulls-eye. The outer bull is worth 25 points and the inner bull is a double, worth 50 points.

There are many variations of rules but in the most popular game the players will begin with a score 301 or 501 and the first player to reduce their running total to zero is a winner. However, it is normal to play a “doubles out” system, which means that the player must land a double (including the double bulls-eye at the centre of the board) on their final dart to win; any other dart that would reduce their running total to one or lower means the score for that set of three darts is “bust”.

When a player is able to finish on their current score it is called a “checkout” and the highest checkout is 170: T20 T20 D25 (two treble 20s and double bull).

There are exactly eleven distinct ways to checkout on a score of 6:

     
D3    
D1 D2  
S2 D2  
D2 D1  
S4 D1  
S1 S1 D2
S1 T1 D1
S1 S3 D1
D1 D1 D1
D1 S2 D1
S2 S2 D1

Note that D1 D2 is considered different to D2 D1 as they finish on different doubles. However, the combination S1 T1 D1 is considered the same as T1 S1 D1.

In addition we shall not include misses in considering combinations; for example, D3 is the same as 0 D3 and 0 0 D3.

Incredibly there are 42336 distinct ways of checking out in total.

How many distinct ways can a player checkout with a score less than 100?


飞镖

在飞镖游戏中,玩家需向靶子上投掷三枚飞镖;靶子被分成了二十个相等面积的区域,并分别标上1至20。

每一枚飞镖的分数还取决于它的位置。落在外围的红/绿色圈以外时为零分,落在黑/白色区域时为一倍得分,而落在外围和中间的红/绿色圈时分别为两倍和三倍得分。

在把子的正中心有两个同心圆,被称为靶心。射中靶心外圈得25分,射中靶心内圈则得双倍50分。

飞镖的规则有许多变种,但最热门的一种是,每个玩家从301分或501分开始,轮流投掷飞镖并减去得分,首先将自己的分数减少到恰好为0的玩家获胜。不过,通常会采用“双倍结束”规则,即玩家在最后一镖必须射中一个双倍区域(包括双倍的靶心内圈)才能判定获胜。若这一轮的得分使得玩家的分数减少到1分或更少,但最后一镖未射中双倍区域,则这一轮的得分“作废”。

玩家在目前的分数下能够获胜则被称为“结分”。最高的结分为170:T20 T20 D25(两个三倍20分和一个双倍靶心)。

当玩家分数为6时,恰好有11种结分方式:

     
D3    
D1 D2  
S2 D2  
D2 D1  
S4 D1  
S1 S1 D2
S1 T1 D1
S1 S3 D1
D1 D1 D1
D1 S2 D1
S2 S2 D1

注意D1 D2被认为是不同于D2 D1的结分方式,因为它们最后的双倍不同。不过,组合S1 T1 D1和T1 S1 D1就被认为是相同的结分方式。

另外,我们在计算组合时,我们不考虑脱靶的情况;例如,D3和0 D3以及0 0 D3就是相同的结分方式。

令人惊奇的是一共有42336种不同的结分方式。

当玩家分数小于100时,一共有多少种不同的结分方式?

解题

飞镖盘官网  看到下面的图

对上面讲的瞬间懂了

理解题意:表盘上的的数组有 1-20、1-20的两倍数、1-20的三倍数、25、50

结分:射击所得分数与自己目前所余分数一样,也就是相减为0,自己是零分。

结分的方式:最后一镖必须射中一个双倍区域

具体分为下面的情况:

1.射击一次结束:一定是双倍数区域

2.射击两次结束:第二次一定是双倍数区域

3.射击三次结束:第三次一定是双倍数区域

Java

package Level4;

import java.util.ArrayList;
import java.util.List; public class PE0109{
public static void run(){
int limit = 100;
int res = 0;
List<Integer> scores = new ArrayList<Integer>();
for(int i =1;i<=20;i++){
scores.add(i);
scores.add(2*i);
scores.add(3*i);
}
scores.add(25);
scores.add(50);
List<Integer> doubles = new ArrayList<Integer>();
for(int i=1;i<=20;i++){
doubles.add(2*i);
}
doubles.add(50);
// 射中双倍结束
for(int i=0;i<doubles.size();i++){
if(doubles.get(i) <limit)
res++;
}
// 射击两次结束
for(int i=0;i< scores.size();i++){
for(int j=0;j<doubles.size();j++){
if(scores.get(i)+doubles.get(j) <limit){
res++;
}
}
}
// 射击三次结束
for(int i=0;i<scores.size();i++){
for(int j=i;j<scores.size();j++){
for(int k=0;k<doubles.size();k++){
if(scores.get(i)+scores.get(j)+doubles.get(k) <limit){
res++;
}
}
}
}
System.out.println(res); } public static void main(String[] args){
long t0 = System.currentTimeMillis();
run();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms");
}
}

Java Code

38182
running time=0s8ms

Python

# coding=gbk

def run1():
from itertools import combinations_with_replacement CHECKOUT_LIMIT = 100 # define dart combinations
SINGLE = range(1, 20+1)
DOUBLE = [2*i for i in SINGLE] + [50]
TREBLE = [3*i for i in SINGLE]
ANY_SCORE = SINGLE + [25] + DOUBLE + TREBLE # throw type 1 - 3 darts - hit, hit, double
throw1 = [(d1, d2, d3) for (d1, d2) in combinations_with_replacement(ANY_SCORE, 2) for d3 in DOUBLE] # throw type 2 - miss, hit, double
throw2 = [(0, d1, d2) for d1 in ANY_SCORE for d2 in DOUBLE] # throw type 3 - miss, miss, double
throw3 = [(0, 0, d1) for d1 in DOUBLE] # calculate checkout total that meets conditions
checkout_tot = sum(1 for (d1, d2, d3) in throw1 + throw2 + throw3 if sum((d1, d2, d3)) < CHECKOUT_LIMIT) print checkout_tot
def run():
res = 0
singles = []
doubles = []
trebles = [] for i in range(1, 21):
singles.append(i)
doubles.append(2*i)
trebles.append(3*i)
singles.append(25)
doubles.append(50)
scores = []
scores += singles
scores += doubles
scores += trebles for s in doubles:
if s<100:
res+=1
for s1 in scores:
for s2 in doubles:
if s1+s2 < 100:
res+=1
for i in range(len(scores)):
for j in range(i,len(scores)):
for s in doubles:
if scores[i] + scores[j] + s< 100:
res+=1
print res if __name__ == '__main__':
run()
run1()

Project Euler 109 :Darts 飞镖的更多相关文章

  1. [project euler] program 4

    上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...

  2. Python练习题 029:Project Euler 001:3和5的倍数

    开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...

  3. Project Euler 9

    题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...

  4. Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.

    In Problem 42 we dealt with triangular problems, in Problem 44 of Project Euler we deal with pentago ...

  5. project euler 169

    project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...

  6. 【Project Euler 8】Largest product in a series

    题目要求是: The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × ...

  7. Project Euler 第一题效率分析

    Project Euler: 欧拉计划是一系列挑战数学或者计算机编程问题,解决这些问题需要的不仅仅是数学功底. 启动这一项目的目的在于,为乐于探索的人提供一个钻研其他领域并且学习新知识的平台,将这一平 ...

  8. Python练习题 049:Project Euler 022:姓名分值

    本题来自 Project Euler 第22题:https://projecteuler.net/problem=22 ''' Project Euler: Problem 22: Names sco ...

  9. Python练习题 048:Project Euler 021:10000以内所有亲和数之和

    本题来自 Project Euler 第21题:https://projecteuler.net/problem=21 ''' Project Euler: Problem 21: Amicable ...

随机推荐

  1. IIS 404.17 错误解决方案

    操作方法:在管理员身份打开命令行,运行以下命令: C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -i

  2. scrapy 错误

    1. 安装win32时候 Unable to find vcvarsall.bat 解决方法: 1.如果你没有安装vc,去微软下个 VS2008 的免费版就能解决此问题. 2.如果你安装的是VS201 ...

  3. 1. VS2010---简介

    VS2010 使用简要介绍 ------------------------------------------------- 1. 几个基本概念---源程序.目标程序和翻译程序. 源程序 就是我们用 ...

  4. 用cmd命令合并N个文件

    今天早上朋友发我一篇小说(42个TXT文件),让我给他合并为一个文件.我首先想到的是“Copy”命令,它可以复制文件,也可以合并文件. 例如:合并1.txt和2.txt到12.txt(其为ASCII文 ...

  5. HTML浅学入门---基础知识 (1)<基本规则>

    HTML: 结构化文档,超文本标记语言 (一)四条基本规则 1.每个开始标记必须和结束标记配套使用.// <tag>    </tag> 2.文档中必须包含唯一的打开和关闭标记 ...

  6. Java实现Tire

    Trie,又称单词查找树或键树,是一种树形结构.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:最大限度地减少无谓的字符串比较,查询效率比 ...

  7. UITableView的常用属性和cell的内存优化

    UITableView的常用属性: 分割线颜色设置: 1> 设置separatorStyle: 分割线的颜色 方法:tableView.separatorStyle = UITableViewC ...

  8. 向Array中添加堆排序

    堆排序思路 堆排序是一种树形选择排序方法(注意下标是从1开始的,也就是R[1...n]). 1) 初始堆: 将原始数组调整成大根堆的方法——筛选算法:比较R[2i].R[2i+1]和R[i],将最大者 ...

  9. [原创] zabbix学习之旅五:如何快速搭建一个报警系统

    通过之前的文章,我们已搭建好zabbix server.agent和mail客户端,现在万事俱备,只差在server的界面中进行相应配置,即可快速搭建一个报警系统.总的来说,快速搭建一个报警系统的顺序 ...

  10. 学习Linux第三天

    1.常用的命令: reset 清屏 leave +hhmm 建立离开提醒 sudo apt-get yum 安装yum程序 sudo su 切换root身份 see test.c 可以直接查看文件,神 ...