Project Euler 109 :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 飞镖的更多相关文章
- [project euler] program 4
上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...
- Python练习题 029:Project Euler 001:3和5的倍数
开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...
- Project Euler 9
题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...
- 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 ...
- project euler 169
project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...
- 【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 × ...
- Project Euler 第一题效率分析
Project Euler: 欧拉计划是一系列挑战数学或者计算机编程问题,解决这些问题需要的不仅仅是数学功底. 启动这一项目的目的在于,为乐于探索的人提供一个钻研其他领域并且学习新知识的平台,将这一平 ...
- Python练习题 049:Project Euler 022:姓名分值
本题来自 Project Euler 第22题:https://projecteuler.net/problem=22 ''' Project Euler: Problem 22: Names sco ...
- Python练习题 048:Project Euler 021:10000以内所有亲和数之和
本题来自 Project Euler 第21题:https://projecteuler.net/problem=21 ''' Project Euler: Problem 21: Amicable ...
随机推荐
- Android HttpClient GET或者POST请求基本使用方法(转)
在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们使用各种Http服务.这里只介绍如何使用HttpCl ...
- Linux下cron的使用
cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业.由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动.关闭这个服务: /sbin/service c ...
- C#判断字符串为空
string str = null; if (string.IsNullOrWhiteSpace(str)) { MessageBox.Show("字符串为null"); } if ...
- HashSet<T>类
HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复出现且无特性顺序的元素. HashSet<T>的一些特性如下: 1 ...
- iOS10推送必看UNNotificationServiceExtension
转:http://www.cocoachina.com/ios/20161017/17769.html (收录供个人学习用) iOS10推送UNNotificationServic 招聘信息: 产品经 ...
- svn中的图标解释
黄色感叹号(有冲突): --这是有冲突了,冲突就是说你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不 允许你提交,防止你的提交覆盖了 ...
- 结队开发项目——七巧板NABC需求分析
NABC需求分析 我们团队项目为七巧板取了个洋气的名字叫7-magic. 怀念过去,把握现在,展望未来:立足经典,勇于创新,开创一个七巧板的新时代. 特点:可以保存图片或上传至微信平台 N ...
- php file_put_contents() 写入回车
PHP file_put_contents() 函数是一次性向文件写入字符串或追加字符串内容的最合适选择. file_put_contents() file_put_contents() 函数用于把字 ...
- MVC缓存技术
一.MVC缓存简介 缓存是将信息(数据或页面)放在内存中以避免频繁的数据库存储或执行整个页面的生命周期,直到缓存的信息过期或依赖变更才再次从数据库中读取数据或重新执行页面的生命周期.在系统优化过程中, ...
- C#使用Socket登陆WordPress源码
就在昨晚,在本屌丝刚刚发布屌丝与女神的回忆史<C#外挂QQ找茬辅助源码,早期开发>后,在苏飞大哥的技术讨论群有个群友提出一个问题.使用http协议模拟工具可以登录成功Wordpress但是 ...