穷举与搜索基础

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长春赛区现场赛的题目改编简化版

posted @ 2015-08-31 09:56  健康平安快乐  阅读(514)  评论(0编辑  收藏  举报