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;
}
原文:http://www.cnblogs.com/tlnshuju/p/6950585.html