题目:
给出n条边,每条边有一定的长度,现在要用所有的边围成三角形,问能够围成多少个不同的三角形(三边至少有一边不等)。
分析:
对三角形进行编号,A,B,C三边,所有的边必定在其中的一条上面,只要三进制压缩枚举每条边所在的位置即可,也可以直接
dfs枚举即可。
另外注意到第一根木棍肯定在三角形的一条边上,所以根据对称关系,可以直接把他放在a号边即可

#include <cstdio> #include <cstring> #include <set> #include <algorithm> using namespace std; const int X = 16; int a[X],n,ans,sum; int b[5]; set<pair<int,int> > ma; void dfs(int pos,int suma,int sumb,int sumc){ if(pos==n){ //这个是判断是否符合条件的,对三边进行排序且判断能否组成三角形 if(suma<sumb){ b[0] = suma; b[1] = sumb; } else{ b[0] = sumb; b[1] = suma; } if(b[0]>sumc) b[0] = sumc; if(b[1]<sumc) b[1] = sumc; b[2] = sum-b[0]-b[1]; swap(b[2],b[1]); if(b[0]+b[1]<=b[2]) return; if(b[2]-b[0]>=b[1]) return; if(ma.find(make_pair(b[0],b[1])) != ma.end()) return; ans ++; ma.insert(make_pair(b[0],b[1])); return; } dfs(pos+1,suma+a[pos],sumb,sumc); dfs(pos+1,suma,sumb+a[pos],sumc); dfs(pos+1,suma,sumb,sumc+a[pos]); } int main(){ freopen("sum.in","r",stdin); int ncase; scanf("%d",&ncase); while(ncase--){ ma.clear(); sum = 0; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); sum += a[i]; } ans = 0; dfs(1,a[0],0,0); printf("%d\n",ans); } return 0; }
可能刚刚改动了数据,我的程序WA掉了==。对大家造成不便,不好意思- -,我已经删了该博文了。。。
更新:1006那题应该是题目的问题,比赛中我就是以该程序对了,但是昨天晚上就不对了,刚才我改动了一处地方i<6改为i<8就对了(或者直接删掉该条件的判断貌似也是对的),貌似是题目大意不清楚,sorry~~