Luo2383:狗哥玩木棒 題解
阿新 • • 發佈:2018-09-30
個數 spa 枚舉 但是 文件中 無法 over false 輸出
寫成了
Problem
題目背景
狗哥又趁著語文課幹些無聊的事了...
題目描述
現給出一些木棒長度,那麽狗哥能否用給出的木棒(木棒全用完)組成一個正方形呢?
輸入輸出格式
輸入格式:
輸入文件中的第一行是一個整數n表示測試的組數,接下來n行表示每組的測試數據。 每行的第一個數為m(4<=m<=20),接下來m個數ai(1<=ai<=1000)表示木棒的長度。
輸出格式:
對於每組測試數據,如果可以組成正方形輸出“yes”,否則輸出“no”。
輸入輸出樣例
輸入樣例#1:
3
4 1 1 1 1
5 10 20 30 40 50
8 1 7 2 6 4 4 3 5
輸出樣例#1:
yes no yes
Solution
呵呵,這居然是的題目,其實是一道暴搜題,相信大家都會寫。
但是,它之所以能被評為是因為純粹的暴搜是無法過了這題的,需要加一些 剪枝。
這是我的提交記錄,可以看到,從一開始的 TLE
到 AC
,時間差距是巨大的,甚至同樣 AC
的代碼也有 5 倍時間的差距。這都是剪枝的操作所導致的。
先來講講怎麽從 TLE
到 AC
,這是我暴搜最初的版本:
bool dfs(int t, int l1, int l2, int l3, int l4){ //t 表示當前到第幾個棍子了,l1,l2,l3,l4分別是正方形的四條邊的長度,返回值表示是否可行 if (t == n + 1){return (l1 == l2 && l2 == l3 && l3 == l4);} if (dfs(t+1, l1 + a[t], l2, l3, l4)) return true; if (dfs(t+1, l1, l2 + a[t], l3, l4)) return true; if (dfs(t+1, l1, l2, l3 + a[t], l4)) return true; if (dfs(t+1, l1, l2, l3, l4 + a[t])) return true; return false; }
這個暴搜沒有經過任何優化,我們需要考慮優化的動機。我們發現,有一些狀態是 沒有必要枚舉下去的,舉個例子,如果 \(sum = \Sigma a_i\),\(sum\) 不是 4 的倍數,那麽顯然不能拼成正方形;進一步,如果 l1,l2,l3,l4
中的某個數大於 \(sum \over 4\),顯然應該返回 false
,沒有必要枚舉下去。
加了這兩個優化,代碼就 AC
了哈。
還能不能進一步優化呢?
思考剛才那個剪枝,因為剪枝肯定是越早越好,如果我們把棍子按照長度降序排列,那麽剪枝的時間肯定會有所提前。這個優化可以把時間優化到原來的 \(1 \over 5\)。
至於我的那個 CE
,是因為降序排序時 sort(a+1, a+1+n, greater<int>() )
sort(a+1, a+1+n, greater<int> )
,話說難道我以前都寫錯了QAQ?Luo2383:狗哥玩木棒 題解