# Orange lecture #3 - The Boggle Game ### 1, Đề bài - Một từ hợp lệ: + Có 4 kí tự chữ cái + Có chính xác 2 nguyên âm (bao gồm y) - Cho 2 bảng 4x4, tìm danh sách các từ chung của 2 bảng này + Một từ trong bảng: * dãy 4 ô phân biệt, 2 ô liên tiếp kề nhau (có đỉnh/cạnh chung) #### Input: - Gồm nhiều dataset, mỗi dataset gồm 1 cặp 2 bảng 4x4, các dataset cách nhau bởi 1 dòng trống - Dòng cuối chứa '#' #### Output: - Với mỗi dataset -> in ra danh sách các từ chung tăng dần hoặc 'There are no common words for this pair of boggle boards.' - Các dataset cách nhau bởi 1 dòng trống ``` Sample input D F F B W A S U T U G I B R E T O K J M Y A P Q K M B E L O Y R Z W A V G S F U U N C O A H F T Y T G I G N A L H G P M B O O B # Sample output: There are no common words for this pair of boggle boards. ANGO AOGN GNAO GOAN NAOG NGOA OANG OGNA ``` ### 2, Ý tưởng - Với mỗi array 4x4 -> backtracking tìm tất cả mọi từ trong bảng + Xuất phát tại 1/16 vị trí bất kì -> đi tiếp 3 lần: mỗi lần chỉ đi qua ô kề chưa được đánh dấu -> Lưu lại mọi từ được đánh dấu của 2 bảng và so sánh rồi in ra ### 3, Implementation ```python # Import STL import sys # List of vowels vowels = 'AEIOUY' # Count 2 vowels def countVowels(word): count = 0 for letter in word: if letter in vowels: count += 1 return count == 2 # Find words of length 4 (backtracking) def findWords(board, cur_row, cur_col, current_word, visited, word_set): # Check if the current_word word is a PigEwu word if len(current_word) == 4: if countVowels(current_word): word_set.add(current_word) return # If the current_word word is not a PigEwu word yet visited[cur_row][cur_col] = True for i in range(8): new_row = cur_row + dX[i] new_col = cur_col + dY[i] if new_row >= 0 and new_row < 4 and new_col >= 0 and new_col < 4: if not visited[new_row][new_col]: new_word = current_word + board[new_row][new_col] findWords(board, new_row, new_col, new_word, visited, word_set) visited[cur_row][cur_col] = False # backtracking # Main if __name__ == '__main__': start = True iTest = 0 while True: # Read the input a = [['A'] * 4 for _ in range(4)] # Board A b = [['A'] * 4 for _ in range(4)] # Board B for i in range(4): S = input().split() # Loop condition if(len(S) <= 1): sys.exit() for j in range(4): a[i][j] = S[j] for j in range(4, 8): b[i][j - 4] = S[j] dX = [-1,-1,-1,0,0,1,1,1] dY = [-1,0,1,-1,1,-1,0,1] visited = [[False] * 4 for _ in range(4)] # Find all PigEwu words setA = set() # all words word_set in set A setB = set() # all words word_set in set B for row in range(4): for col in range(4): # visited[row][col] = True # find all words starting from (row, col) findWords(a, row, col, a[row][col], visited, setA) findWords(b, row, col, b[row][col], visited, setB) # visited[row][col] = False # backtracking result = [] # all PigEwu words appearing in both sets for word in setB: if(word in setA): result.append(word) # Print the resultult iTest += 1 if(iTest > 1): print() if(len(result) <= 0): print('There are no common words for this pair of boggle boards.') else: result.sort() for word in result: print(word) input() ``` ### 4, Độ phức tạp: - Với mỗi bảng: + Mỗi từ: kí tự thứ nhất có 16 cách chọn, kí tự thứ hai có 7 cách chọn, kí tự thứ ba/bốn có 7 cách chọn => Tối đa: 16 * 7^3 từ = W => Lưu vào set (hash table)/kiểm tra tồn tại trong set trong O(1) => O(W) + Sort lại các từ trong O(WlogW) => Toàn bộ: O(T * WlogW)