Project Euler 109 :Darts 飛鏢

來源:互聯網
上載者:User

標籤:

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
38182running time=0s8ms

Python

# coding=gbkdef 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_totdef 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 飛鏢

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.