美國ACSL計算機科學競賽--編程題真題解析及代碼(初級)

abc_3_jr

  題目要求:在一個3乘3的網格中填A,B,C三個字母使其橫縱每行每列的每個字母不重複出現,相當於三階數獨。位置按照每行1,2,3依次遞增。

  輸入:1.輸入先放置的字母數量2.輸入放置的字母以及位置

  例:3,1,A,3,C,8,A

  輸出:依次按照位置輸出全部字母。

  例:ABCBCACAB

  解題思路:

  思路1:一個三階數獨確定它的唯一性就是有兩個已知的不同字母在不同行不同列,這樣就可以確定是唯一解。所以先要根據條件找到這兩個字母,然後將這個網格當做一個二維座標系,這兩個字母的座標設爲(x1,y1(x2,y2),因爲座標取值範圍爲(0-2)因此x3也可以得出。那麼根據三階數獨規律若已知a,b(此ab是作爲替代可以是ABC中任意一個)那麼(x1,y2)

(x2,y1)就爲c依次類推可以得出所有的格子對應的字母。具體可以詳見代碼。

  思路2:摒棄法,列出來所有三階數獨組出來的數列,然後根據題目的輸入內容進行匹配得出,進行窮舉法將A,B,C可以認爲是1,2,3然後用itertools包先讓A,B,C進行全排列,因爲要滿足每行每列字母不重複,那麼每行每列相加的和只要等於6就確定他們不重複,將這些進行帶入進行判斷得出所有可能。(代碼中摒棄法給出得出所有排列的代碼)

思路一代碼段:

# 案例輸入 3   1A  3C  8A 結果 ABCBCACAB
# 在3×3的網格中放置ABC三個字母並填滿使得每一行每一列都只有某個字母的一個
content = input("請輸入:").split(',')
number = int(content[0])
result_list = [['0', '0', '0'],
               ['0', '0', '0'],
               ['0', '0', '0']]
locations = []
L = ["A", "B", "C"]
#  首先將錄入的位置和字母化爲對應的列表的x,y座標放入一個列表當中
for i in range(number):
    location = int(content[2*i+1])
    letter = content[2*i+2]

    row = ((int(location) - 1) % 3)
    col = (int(location) - 1) // 3
    locations.append([[col, row], letter])
fill_location = []
#  需要判斷是否輸入的數量大於2,如果大於2需要找出來橫縱座標不同且字符也不同的兩個
if number >= 2:
    for i in range(number):
        for j in range(i + 1, number):
            if locations[i][0][0] != locations[j][0][0] and \
                    locations[i][0][1] != locations[j][0][1] and \
                    locations[i][1] != locations[j][1]:
                fill_location.append([locations[i][0], locations[i][1]])
                fill_location.append([locations[j][0], locations[j][1]])
                break
#  將已知的兩個位置的座標設爲x1,y1 x2,y2 然後再根據其得到x3,y3 這樣就可以表示x(0-2) y(0-2))
x1, y1 = fill_location[0][0][0], fill_location[0][0][1]
x2, y2 = fill_location[1][0][0], fill_location[1][0][1]
for i in range(3):
    if i != x1 and i != x2:
        x3 = i

for i in range(3):
    if i != y1 and i != y2:
        y3 = i
result_list[x1][y1] = fill_location[0][1]
a = fill_location[0][1]
result_list[x2][y2] = fill_location[1][1]
b = fill_location[1][1]
L.remove(a)
L.remove(b)
c = L[0]
# 往網格里填寫ABC
result_list[x1][y2] = c
result_list[x2][y1] = c
result_list[x3][y1] = b
result_list[x1][y3] = b
result_list[x3][y2] = a
result_list[x2][y3] = a
result_list[x3][y3] = c
result = ''
for i in result_list:
    for j in i:
        result = result + j
print(result)

思路二代碼段


# 引入itertools包
import itertools
# 行、列、主副對角線的和都應該是6,先用count
count = 0
# #創建1-9的集合
nums = [x for x in range(1,10)]
# 創建一個累加和爲6的3個數的序列
sequence_3nums = [p for p in itertools.permutations(nums, 3) if sum(p) == 6]
# 開始迭代,一共三列
# sequence_3nums = [[1], [2], [3]]
for row1_1, row1_2, row1_3 in sequence_3nums:
    for row2_1, row2_2, row2_3 in sequence_3nums:
        for row3_1, row3_2, row3_3 in sequence_3nums:
            # 判斷橫縱三列的和是不是6
            if row1_1 + row1_2 + row1_3 == 6 \
                and row2_1 + row2_2 + row2_3 == 6 \
                and row3_1 + row3_2 + row3_3 == 6 \
                and row1_1 + row2_1 + row3_1 == 6 \
                and row1_2 + row2_2 + row3_2 == 6 \
                and row1_3 + row2_3 + row3_3 == 6:
                    count = count + 1
                    print(20 * '*')
                    # print(row1_1, row1_2, row1_3)
                    # print(row2_1, row2_2, row2_3)
                    # print(row3_1, row3_2, row3_3)
                    return_list = [row1_1, row1_2, row1_3, row2_1, row2_2, row2_3, row3_1, row3_2, row3_3]

                    for i in return_list:
                        if i == 1:
                            print('A', end='')
                        if i == 2:
                            print('B', end='')
                        if i == 3:
                            print('C', end='')
                    print('第' + str(count) + '個結果')

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章