iwehdio的:
初賽賽題題目、資料、源**、提交的文件、複賽答辯ppt和決賽題目見:
初賽使用python語言,初賽第二階段執行時間在6~7s。初賽第一,決賽參與獎。
剛開始對題意有乙個初步的了解。要求的是最大的數量,所以跟每人準備的數量無關,而是只跟朋友關係的複雜程度有關。
將部落中的每個人進行編號,按正負區分部落。用陣列記錄禮物傳遞的路徑。
用深度優先搜尋來對禮物傳遞路徑進行搜尋。但是搜尋的效率很低,只能對環長為4和6的路徑進行搜尋。
在深度優先搜尋的同時進行去重,包括路徑內部不重複的內去重和路徑之間不重複的外去重。
嘗試剪枝策略,比如記錄路徑中的第乙個和第二個節點的編號,並對其在之後的路徑中進行處理。可以搜尋到環長為10的路徑。
將搜尋一整個路徑分解為搜尋兩個半路徑,然後拼接起來。可以對14環進行搜尋了。去重策略又多了乙個半路徑的內去重。
尋找資料中的規律,發現了鄰接矩陣是由多個等間隔的分塊矩陣構成的,而且每個分塊矩陣都可以通過矩陣中第乙個點的平移得到。
利用規律,對每個分塊矩陣,先對第乙個節點進行搜尋,在此基礎上對該分塊矩陣中的每個節點進行去重。
優化規律的使用,利用有序等特點,更換資料結構等對細節進行優化。
讀入資料,定義全域性變數。
# 記錄程式開始的時間,讀取csv資料
time0 = time.time()
file_path = r"../data/part2/5.8/example.csv"
table =
with open(file_path, 'r') as f:
reader = csv.reader(f)
for row in reader:
# 定義全域性變數
global number
global head
global interval
global l
global s
aims = [2, 3, 4, 5, 6, 7]
countall =
l, s = {}, {}
# 將鄰接矩陣轉換為鄰接表
source = [ for i in range(len(table) + len(table[0]) + 1)]
for i in range(len(table)):
for j, v in enumerate(table[i]):
if v == '1':
def get(num):
return source[num]
根據不同的資料大小,判斷資料間隔。
if len(table) == 1344:
interval = 192
elif len(table) == 256:
interval = 64
index = [1]
for i in range(1, int(len(table) / interval)):
迴圈進行所有環長的搜尋。
for x in aims:
count = 0 # 初始化不同長度的環的數量
for p1 in index: # 不同區域的起始點
p2 = p1 + interval - 1 # 不同區域的終點
number = x # 設定環長度、頭節點,並進行傳遞
head = p1
count += convert(p1, p2)
呼叫的函式。
函式dfs()
。
def dfs(num, length, depth, path):
if depth == length: # 如果達到期望的路徑陣列,將其排序標準化後,
# print(number*2, " ", path) # 存入 s 字典,鍵為半路徑的尾節點(如果該半路徑未被找到)
tr0 = tuple([path[-1]])
temppath = path[1:-1] +
temppath.sort()
if tr0 in s.keys(): # 判斷該半路徑是否已經被找到
if temppath not in s[tr0]:
else:
s[tr0] = [temppath]
return
for j in get(num): # 向下搜尋
if (j < 0 or j > head) and (j not in path): # 去除半路徑中已有的和編號大於頭節點的資料
dfs(j, length, depth + 1, path + [j])
函式repeat()
。
def repeat(m, n):
for i in m:
if i in n:
return false
return true
函式checkin()
。
def checkin(c, p1, p2):
if c not in l.keys():
l[c] = ''
return checkdiff(c, p1, p2) + 1
return 0
函式checkdiff()
。
def checkdiff(c, p1, p2): # 判斷這個環能衍生出多少有效環
max_num = p1 - 1
for i in c[number:]: # 排序好的陣列,前半部分是負的,不需要比較
if i > max_num: # 判斷是否在範圍中,越過右邊界則不再比較
if i > p2:
break
max_num = i
return p2 - max_num
同時,由於傳入的路徑是排序好的陣列,前半部分編號為負,不需要比較。同樣的,大於終點編號後,也不需要再比較。
優化:搜尋和去重的效率較低,應該有更為快速的方法。
iwehdio的:
2020中興捧月傅利葉派記錄
前段時間看到了同學 的中興通訊的比賽鏈結,之前也沒有參加過演算法類的比賽,這次打算報著試一試的態度參加下,增加下經驗。在初步看了幾個門派的題目簡介後,發現只有傅利葉派比較適合自己,所以最終選擇了傅利葉派。目錄 在某片遙遠的大陸上,居住著兩個世代友好的部落,分別是部落a和部落b。他們一起耕耘勞作,互相...
中興捧月 傅利葉 豐收祭前的遊戲(果然菜)
在某片遙遠的大陸上,居住著兩個世代友好的部落,分別是部落a和部落b。他們一起耕耘勞作,互相幫助,親如一家。久而久之,部落裡的每個人都在對方部落裡找到了志趣相投,互相欣賞的好朋友。有的人性格熱情開朗,好朋友很多 有的人性格沉穩內斂,好朋友相對少一些。每到秋天豐收的季節,這兩個部落的人民都會聚集在一起舉...
No 4 中興捧月競賽總結
今天天熱,就睡實驗室了,開著空調。夜裡,沒心情睡覺,今天中興程式競賽複賽結果已出,沒能殺進決賽,有點小遺憾。但回想起來,從 4月份開始,經歷組隊,預賽選拔,初賽,複賽,一路走來還是深有感觸。個人而言,對任何事如果說只注重過程,不關注結果,那絕對是一句安慰人的話。凡事盡力而為之,盡力求得更好結果。旅程...