演算法學習(十三),演算法學習
1.Funny Words Generator
說明:編寫一個程式,可以產生一組有趣的單詞。
讓我們按照以下步驟進行工作:
1.單詞有任意數量的字母,但是字母在奇數位置(1、3、5、……)應該是輔音,而字母的偶數位置(2、4、6、……)應該是母音。
2.規定輔音字母是 bcdfghjklmnprstvwxz,母音是 aeiou (注意q和y跳過)。
3.用參數實現簡單的線性同餘產生器,參數A=445,C=700001,M=2097152,初始值X0作為輸入資料(即種子)。公式:Xnext = (A * Xcur + C) % M
4.要產生由N個字母組成的單詞,用這個產生器產生的隨機數作為初始值,產生下一個隨機數,例如,在X0=0和N=4的情況下,你將得到 700001,1821950,1967079,1537772 這四個數。
5.將這些隨機值轉換為字母,通過對輔音或5母音的位置進行索引,並從上面的字串中選擇字母(參見步驟2)。
例如,如果X0=0我們要產生4個字母的單詞,我們有如下的計算:
Random Value Letter Index Letter 700001 700001 % 19 = 3 F # f的索引為3,那麼就在輔音的第四個位置上。 1821950 1821950 % 5 = 0 A # a的索引為0,那麼就在母音的第一個位置上。 1967079 1967079 % 19 = 9 M 1537772 1537772 % 5 = 2 I
因此得到的單詞是fami。
輸入資料:在第一行中包含產生的單詞數量和隨機產生器的種子值X0。
下一行中包含應該產生的單詞長度,並與空格分隔。
答案:應該包含你所產生的單詞,並由空格分隔。
例如:
input data:3 04 5 6answer:fami wovaw kelasi
另一個例子:
input data:4 20149 9 9 9answer:foravanad zibecefeb wagabenip wedivonow
測試資料:
23 3449854 3 6 7 6 8 3 8 7 7 4 6 6 8 7 7 8 3 6 8 3 8 6
代碼如下:
1 consonant = 'bcdfghjklmnprstvwxz' 2 vowels = 'aeiou' 3 4 test_case = input().split() # 測試案例數 5 6 A = 445 7 C = 700001 8 M = 2097152 9 X = int(test_case[1])10 nums = [int(i) for i in input().split()]11 for N in nums:12 total = [] # 找到產生的隨機數13 while N > 0:14 N -= 115 X = (A * X + C) % M 16 total.append(X)17 letters = []18 for i in total:19 if total.index(i) % 2 == 0:20 n = i % 1921 letter = consonant[n] # 通過索引找到字元22 letters.append(letter)23 elif total.index(i) % 2 != 0:24 n = i % 525 letter = vowels[n]26 letters.append(letter)27 word = ''.join(letters) # 合并字元28 print(word, end=' ')29 30 輸出:hodu tob vapola cizilah selapi hirugife wam nocofavo buhinut xuweduf suto gonobe rinuki votawezu juragah topilin rawotisi nij facicu gucocada jen lebumuci fuline
2.Tic-Tac-Toe
說明:井字遊戲的一種演算法——檢查功能,它可以判斷遊戲是否結束,並由一個或另一方獲勝。
這個遊戲是在方塊3 x 3上進行的。讓我們假設這些方塊命名為1到9個數:
1 | 2 | 3---+---+--- 4 | 5 | 6---+---+--- 7 | 8 | 9
兩名玩家將他們的標記(X為第一,O為第二)依次轉換為任何剩餘的數字方塊。一方完成了3個標記(3個x或3個o)的直線,馬上就會贏。即每行每列和兩個對角線,共8中贏的情況。例如,下面是X和O的步驟:
X O------- 7 5 4 1 9 2 8
上面步驟形成了下面的方塊情況:
O | O | ---+---+--- X | O | ---+---+--- X | X | X
第一個玩家(X字)通過第三排連成一線,贏的遊戲。
問題陳述:
你將得到一系列的移動序列(假設第一步是由X完成的),由標記被放置的儲存格的數量,而你的任務是確定哪一步完成了連成一線的情況(任何一方連成一線都可以,不過要最先完成的一方)。
輸入資料:第一行中包含測試案例數。
下面每行有一個測試案例——正好是9個數字,描述了按順序執行的儲存格。
答案:應該包含玩家在遊戲中獲勝時在第幾步(從1開始計,到9為止,共9步,即輸出在第幾步獲勝),如果在最後一次移動後(沒有贏家)沒有玩家獲勝則輸出 0 。
例如:
input data:37 5 4 1 9 2 8 3 6 # 在第7步獲勝5 1 3 7 6 4 2 9 8 # 在第6步獲勝5 1 2 8 6 4 7 3 9 # 沒有人獲勝,輸出0answer:7 6 0
測試資料:
159 7 6 8 5 3 2 1 44 1 5 6 3 8 2 9 71 8 2 5 4 3 7 9 64 8 5 1 9 6 2 3 77 6 9 4 5 2 1 8 38 4 9 5 3 7 1 2 69 3 8 7 6 1 5 2 48 3 9 2 1 4 6 7 51 7 8 9 6 2 5 4 36 1 5 2 4 3 7 9 88 9 1 6 7 4 2 3 53 9 1 7 2 5 4 8 69 5 1 4 8 3 6 7 21 5 4 8 9 3 6 2 76 8 9 3 2 1 4 5 7
代碼如下:
1 test_cases = int(input()) 2 win = [ 3 {1, 2, 3}, 4 {4, 5, 6}, 5 {7, 8, 9}, 6 {1, 4, 7}, 7 {2, 5, 8}, 8 {3, 6, 9}, 9 {1, 5, 9},10 {3, 5, 7}11 ]12 # 所有贏的比賽的位置條件13 14 def ans(Xs, Os):15 A = []16 for i in win:17 if i & Xs == i or i & Os == i: # 如果win中的子集和Xs或Os的交集等於子集自己,表示有人贏的遊戲18 a = max(data.index(x) for x in i) + 1 # 找到一方贏的遊戲是的索引位置19 A.append(a)20 if len(A) > 0:21 print(min(A), end=' ') # 最先贏的遊戲的索引22 else:23 print(0, end=' ') # 都沒有贏24 25 for _ in range(test_cases):26 data = [int(m) for m in input().split()]27 Xs = set(data[::2]) # X的位置28 Os = set(data[1::2]) # O的位置29 ans(Xs, Os)30 31 輸出:9 9 7 0 7 9 8 9 0 5 8 5 8 8 0