演算法學習(十一),演算法學習
1.King and Queen
說明:像國際象棋這樣的遊戲演算法編程有兩個主要任務:
1.評估位置,檢查哪些部分可以走;
2.構造一種極小的演算法來選擇移動到最優值的位置。
讓我們先來解決一個簡單的問題:有一個棋盤,有8 x 8個方格。上面有白色的國王和黑色的女王。檢查女王是否能吃掉國王。
女王可以垂直、水平的或沿任何兩個對角線移動到任何距離。
8 - Q - - - - - - - - - - - - - -7 - - - - Q - - - - - - - - - Q -6 - - - - - - - - - - - - - - - -5 - - - - - - - - - - - Q - - - -4 - K - - - - Q - - - Q - - - - -3 - - - - - - - - - - - - - - - -2 - - - Q - - - - - - - - - K - -1 - - - - - - - - - Q - - - - - - a b c d e f g h a b c d e f g h
看看這兩個例子,用圖表繪製的板。在這兩種情況下,國王都用字母K表示,而字母Q則顯示了女王的不同位置。
在左邊的棋盤中,國王可以被四個女王中的任何一個“吃掉”;
在正確的棋盤中,國王處於安全的位置——四個女王中沒有一個能吃掉他。
輸入資料:第一行中包含測試案例數。
下面一行描述每個test_case的國王和王后的位置,通過指定它們的方塊(國王是第一個)。
答案:每一個測試給出一個字母Y或N,這代表國王能否被吃掉。用空格間隔。
例如:
input data:8b4 b8b4 e7b4 d2b4 g4f2 b1f2 c4f2 d5f2 g7answer:Y Y Y Y N N N N
測試資料:
26f4 e8c4 b6h2 h8h8 f8e8 d3a8 c6g7 h8d3 e2g1 a2e2 g5c7 d3f2 b3a6 e2e7 g4f7 c2b7 c1h3 b5e1 a7g4 b5e4 g6a3 h5b6 h7e3 h6a3 f1e7 e1g6 h6
代碼如下:
1 horizontally = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] # 水平的座標表示 2 3 test_cases = int(input()) # 測試案例數 4 5 for i in range(test_cases): 6 data = input().split() 7 K, Q = data[0], data[1] # 得到K,Q的座標 8 if K[0] and Q[0] in horizontally: 9 if K[0] == Q[0] or K[1] == Q[1]: # 當K,Q橫縱座標有一個相同,則為Y10 print('Y', end=' ')11 elif abs(horizontally.index(K[0]) - horizontally.index(Q[0])) == abs(int(K[1]) - int(Q[1])):12 print('Y', end=' ') # 當兩座標的橫縱座標之差相等,也為Y13 else: # 其他情況為N14 print('N', end=' ')15 16 輸出:N N Y Y N Y Y Y N N N N Y N N N N N N Y N N Y N Y Y
2.Cards Shuffling(洗牌問題)
說明:對於任何類型的紙牌遊戲來說,洗牌是很重要的。因為只有很少的程式設計語言有內建函數來隨機地對數組進行隨機處理(比如PHP),所以有必要學習一些有用的演算法。
用下列符號來描述卡牌:
ranks: A, 2, 3, 4, 5, 6, 7, 8, 9, T, J, Q, Ksuits: C, D, H, S
CQ是“梅花Q”,HT是“心桃10”,D2是“方塊2”,SA是“黑桃A”。
總共有52張牌,所以在洗牌之前,它們應該被放入52個元素的數組中。該數組的初始順序如下:13張梅花牌,13張方塊牌,13張紅心牌,最後13張黑桃牌。每個花色卡的內部都是由Ace排列到King的,所以整個甲板看起來是這樣的:
[ CA, C2, C3, ..., CQ, CK, DA, D2, ..., DK, HA, H2, ..., HK, SA, S2, ..., SK ]
然後你應該對每張卡片產生一些隨機數在0。將這張牌與另一張牌交換,佔據所選的位置(讓數組的索引從0開始)。
FOR i = 0 ... 51 : LET j = RANDOM(0 ... 51) SWAP deck[i] WITH deck[j]
例如,我們取第一張卡CA,並為它產生隨機值15,這意味著該卡應該移動到位置15,D3在那裡,D3應該被移回位置0。然後我們從位置1中取出C2然後產生下一個隨機數50,所以C2和平方交換。等等。
你將會得到一個非負整數隨機數位序列——如果它們大於必要的數字,那麼就把它們調整到需要的範圍,取52的模數。
輸入資料:將包含52個非負整數,您應該使用它們來像描述的那樣進行洗牌。
答案:應該包含洗牌數組的卡片,和空格分開。
例如:
input data:5814 1316 2080 2712 0 647 8098 315 44 6354 7867 100 61 763 6731 685 42 9309 569 92 701 562 85 8311 698 220 929 71 684 518 113 61 19 168 745 16 655 9548 6018 2686 25 785 81 721 964 85 44 614 4 509 8708 19answer:C5 D5 S4 C8 CQ S3 HK C9 H3 H6 D3 ST DT HT C6 CK DA H9 SJ SK DK C2 DQ S5 H4 D7 S7 S2 C4 D9 CT HJ HQ D2 SA CA H5 H2 C7 D4 CJ D6 S9 HA S8 D8 S6 SQ C3 DJ H8 H7
測試資料:
0 537 320 6335 7581 140 4682 9944 2755 438 897 48 17 406 82 2368 1402 3179 524 3802 37 81 4993 68 6792 32 206 1300 61 43 950 244 44 550 5140 2434 4513 72 4007 726 51 66 8439 9450 956 872 363 100 679 436 48 739
代碼如下:
1 ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'] 2 suits = ['C', 'D', 'H', 'S'] 3 start_deck = [] 4 for i in range(52): 5 suit = i // 13 6 rank = i % 13 7 card = suits[suit] + ranks[rank] 8 start_deck.append(card) # 構造初始化牌組,按要求排好 9 10 num = input().split()11 nums = []12 for i in num:13 nums.append(int(i) % 52) # 得到隨機的位置數14 15 m = 016 for n in range(52):17 start_deck[n], start_deck[nums[m]] = start_deck[nums[m]], start_deck[n] # 按規則交換賦值卡牌18 m += 119 20 for i in start_deck: # 格式化輸出卡牌21 print(i, end=' ')22 23 輸出:H2 CT C7 S9 D6 HJ D7 C8 SK D3 DA S8 C2 S4 H6 HT DJ CK S3 C9 SJ H4 D5 SQ H7 DQ D4 CA DT C4 H8 C6 S6 H5 DK CJ C5 HQ D9 HA S7 D2 H3 S5 D8 C3 S2 CQ SA H9 HK ST