- 题解:
- 列举每一种3的倍数的组合,开始先求出3条边的可行解,则
- 六条边的可行解可以由两个三条边得来。
- 详见代码解析
#include<bits/stdc++.h> using namespace std; int a[22],n,cnt,ant,is[500007],dp[1050007]; struct node { int num,id; }angle[500007]; bool cmp(const node& a,const node& b) { return a.num<b.num; } int abs1(int x) { if(x<0)return -x; return x; } void init() { for(int i=0;i<(1<<n);i++) { int ans=0,t=i; while(t) { if(t&1)ans++; //这一位是1节++ t=t>>1; //右移 } if(ans%3==0) { angle[cnt].id=i; angle[cnt++].num=ans/3; } if(ans==3) { int v[4],ans1=0,ans2=0,t=i; while(t) { //把二进制位是1的边对应上 if(t&1)v[ans1++]=a[ans2]; t=t>>1; ans2++; } if(abs1(v[1]-v[2])<v[0]&&abs1(v[1]-v[0])<v[2]&&abs1(v[2]-v[0])<v[1]) { //两边只差小于第三边,和会超int is[ant++]=i; dp[i]=1; } } } } int main() { int T,cas=0;scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); cnt=0,ant=0; memset(dp,0,sizeof(dp)); dp[0]=1; init(); sort(angle,angle+cnt,cmp);//要排序 for(int i=0;i<cnt;i++) { node e=angle[i]; for(int j=0;j<ant;j++) { //&位运算 if(dp[e.id]&&!(e.id&is[j]))//若e.id已存在并且 //.e.id中的边与is[j]中没有重边则dp[e.id|is[j]]=1 dp[e.id|is[j]]=1;//推到下一个 } } for(int i=cnt-1;i>=0;i--) { if(dp[angle[i].id]) //答案要最多,从后往前遍历 { printf("Case #%d: %d ",++cas,angle[i].num); break; } } } return 0; }