Luo2383:狗哥玩木棒 题解
Posted yjzoier
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luo2383:狗哥玩木棒 题解相关的知识,希望对你有一定的参考价值。
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:狗哥玩木棒 题解的主要内容,如果未能解决你的问题,请参考以下文章