穷举与搜索基础
1. 题目描述
蒜头君一天闲来无事和小萌一起玩游戏,游戏的内容是这样的:他们不知道从哪里找到了N根不同长度的木棍,看谁能猜出这些木棍一共能拼出多少个不同的不等边三角形。注意在拼三角形的时候一定要用上所有的N根木棍哦。不同的定义是至少有一条边的长度不相同;不等边的定义是三条边都不相等。
蒜头君和小萌数学都不太好,每个人都猜到一个数字后才意识到他们并不知道正确答案。于是他们来请教聪明的你,能帮他们算出正确答案么?
输入格式:
第一行为数据组数T,(1<=T<=15)。
接下来每组数据占两行,第一行为木棍的数量N(1<=N<=15)
第二行有N个正整数li (1<=li<100),表示N个木棍的长度。保证每个长度都不相同。
输出格式:
每组数据输出一个非负整数,表示能组成的不同的三角形个数。
样例输入:
1
3
2 3 4
样例输出:
1
2. 解析
读者可以想一下,如果是自己手工计算的话,是怎样的过程呢?是不是把木棍顺次摆放,每次从中不重复的选取三根再判断一下能不能组成三角形就好了?这就是穷举法的思路,没错,这是个和我们平时思路非常接近的算法哦(≧∇≦)来来来,跟随我一起写出这道题的代码吧。
3. 代码实现
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int n ,l[15]; bool h[100000]; bool is_triangle(int a, int b, int c) { return !h[a * 100 + b] && a && b && c && a + b > c && a + c > b && b + c > a && (h[a * 100 + b] = true); } int dfs(int index, int a, int b, int c) { if (index == n) { return a < b && b < c && is_triangle(a, b, c); } return dfs(index + 1, a + l[index], b, c) + dfs(index + 1, a, b + l[index], c) + dfs(index + 1, a, b, c + l[index]); } int main() { int T; scanf("%d", &T); while (T--) { scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d", &l[i]); } memset(h, 0, sizeof(h)); printf("%d\n", dfs(0, 0, 0, 0)); } return 0; }
4. 题源
2012年ACM长春赛区现场赛的题目改编简化版
智慧在街市上呼喊,在宽阔处发声。