标签:ssi hang key source panel har search pac void
1 3 2 3 4
1
题意:给你n条边。组成一个三角形。求能组成的三角形种数。两个三角形三条边一样的算一种。
题解:暴力枚举第一条边。然后双向枚举第二条边,用map去重。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#define MP(x,y) make_pair(x,y)
using namespace std;
typedef pair<int,int > ppi;
map<ppi,int> mp;
int a[20];
int b[20];
int sum;
int all;
int bn;
int ans;
int smallest;
int largest;
void dfs(int i,int csum) {
    if(csum>smallest)
        return ;
    if(csum!=0&&all-csum<=largest&&mp.find(MP(csum,all-csum))==mp.end()) {///成立&&判重
        ans++;
        mp[MP(csum,all-csum)]=1;
    }
    if(i==bn)
        return ;
    dfs(i+1,csum+b[i]);
    dfs(i+1,csum);
}
int main() {
    int n;
    int t;
    scanf("%d",&t);
    while(t--) {
        mp.clear();
        scanf("%d",&n);
        sum=0;
        ans=0;
        for(int i=0; i<n; i++) {
            scanf("%d",a+i);
            sum+=a[i];
        }
        int m=(1<<n)-1;
        for(int i=1; i<m; i++) {///枚举第一条边
            all=0;
            bn=0;
            for(int j=0; j<n; j++) {///第二条与第三条边的和
                if((1<<j)&i) {
                    all+=a[j];
                    b[bn++]=a[j];
                }
            }
            largest=sum-all;
            if(largest>=all)
                continue;
            smallest=all/2;
            dfs(0,0);
        }
        printf("%d\n",ans);
    }
    return 0;
}
标签:ssi hang key source panel har search pac void
原文地址:http://www.cnblogs.com/tlnshuju/p/6950585.html