Python入門習題(87)——OpenJudge百練習題:判斷遊戲勝者

OpenJudge百練第4111號習題:判斷遊戲勝者

題目描述

來源
OpenJudge網站 —— 百練習題集-第4111號習題

要求
總時間限制: 3000ms 單個測試點時間限制: 1000ms 內存限制: 65536kB

描述

Alice和Bob在玩一個遊戲,每一局中他們每人獲得一個16進制數串,計算它對應的二進制數串中有多少個連續的1序列塊(單個的1也算作序列塊)。塊數多者勝利,請判斷遊戲的勝者並輸出,若平局則輸出Tie,比如樣例中的第一組數據爲Alice: 0xfa425 Bob: 0xab3672。Alice的數據轉換爲2進制串後爲11111010010000100101, 其中有6個連續的1序列塊。Bob的數據轉換爲2進制串後爲 101010110011011001110010 其中有8個序列塊,故勝者爲Bob。

輸入
第一行爲遊戲局數正整數n,接下來n行每行由兩部分組成,前者是Alice獲得的16進制數串,後者是Bob獲得的16進制數串,中間用空格隔開。
輸出
每一行輸出一局的勝者。
樣例輸入
2
0xfa425 0xab3672
0x52c6 0xf429
樣例輸出
Bob
Tie

解題思路

  1. 關鍵問題是求出16進制串換成二進制串後,二進制串中1序列塊的數目。
  2. Python語言中,16進制串串換成二進制串的做法是,先調用int(hex, 16)把16進制串hex換成整數number,而後調用bin(number)換成二進制串。
  3. 求出二進制串1序列塊的數目的做法是,從左到右掃描每一位,遇到打頭的1字符,則把1序列塊的數目加1,接着跳過連續的1;遇到0字符,跳過。下面的代碼中,sub1_num函數求出二進制串中1序列塊的數目。jump_to_0函數跳過連續的1字符。

參考答案

#跳過連續的1字符,求出二進制字符串bin_str內索引index位置後第一個0字符的位置,或者是字符串結尾
def jump_to_0(bin_str, index):
    while index < len(bin_str):
        if bin_str[index] == '1':
            index += 1
        else:
            return index
    return index

#求二進制字符串中1序列塊的數量
#bin_str是二進制字符串,以0b打頭。
def sub1_num(bin_str):
    count = 0
    index = 2
    while index < len(bin_str):
        if bin_str[index] == '1':  #遇到打頭的1字符
            count += 1
            index = jump_to_0(bin_str, index)   #跳過連續的1字符
        else:
            index += 1  #遇到0字符,索引增1
    return count

# assert sub1_num('0b0') == 0
# assert sub1_num('0b1') == 1
# assert sub1_num('0b101') == 2
# assert sub1_num('0b1010') == 2
# assert sub1_num('0b11110001100110') == 3
# assert sub1_num('0b1111111111') == 1

n = int(input())
for i in range(n):
    Alice, Bob = input().split()
    Alice = bin(int(Alice, 16))  #先把十六進制串轉換爲整數,然後轉換爲二進制串
    Bob = bin(int(Bob, 16))  #int函數的第二個參數16,表明Bob字符串是16進制的
    # print(Alice, Bob)
    sub1_num_Alice = sub1_num(Alice)  #求出Alice拿到的串的1序列塊的數目
    sub1_num_Bob = sub1_num(Bob)
    if sub1_num_Alice > sub1_num_Bob:
        print("Alice")
    elif sub1_num_Alice == sub1_num_Bob:
        print("Tie")
    else:
        print("Bob")

測試用例

  1. 題目描述給出的測試用例有兩組測試數據。第一組測試數據覆蓋了數目不等的情形。第二組測試數據覆蓋了1序列塊數目相等的情形。
  2. 上一節給出的代碼中的assert語句,驗證了sub1_num函數的正確性。有了這個,無需更多測試用例。因爲我相信,除開sub1_num函數封裝的求二進制串中1序列塊數目的邏輯,其他代碼是簡單直接的,不會出錯。
  3. 不放心的話,令n=1,Alice拿到全0的,Bob拿到全1的。
    樣例輸入
    1
    0x0 0xff
    樣例輸出
    Bob

小結

  1. Python語言提供了從16進制字符串轉換爲整數的函數和把整數轉換爲二進制串的函數。
  2. 用函數來封裝一個子步驟,能夠繞開兩重循環。本例中,jump_to_0函數起到了這個作用。如果沒有使用該函數,那麼代碼邏輯的複雜度將顯著上升。有了該函數,代碼變得清晰簡潔。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章