uva 1354 Mobile Computing ——yhx
1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 struct node 5 { 6 int fat,lson,rson; 7 double wei; 8 }tree[500]; 9 double w[10],lim,ans; 10 int n; 11 double max(double x,double y) 12 { 13 return x>y?x:y; 14 } 15 void calc_sub(int p,double &l,double &r) 16 { 17 int i,j,k; 18 double l1,r1,l2,r2,x,y; 19 if (tree[p].lson) 20 { 21 calc_sub(tree[p].lson,l1,r1); 22 calc_sub(tree[p].rson,l2,r2); 23 } 24 else 25 l1=r1=l2=r2=0; 26 x=tree[tree[p].rson].wei/tree[p].wei; 27 y=tree[tree[p].lson].wei/tree[p].wei; 28 l=max(l1+x,l2-y); 29 r=max(r1-x,r2+y); 30 } 31 void calc() 32 { 33 int i,j,k,p; 34 double l,r; 35 for (i=1;i<=2*n-1;i++) 36 if (tree[i].fat==0) 37 { 38 calc_sub(i,l,r); 39 if (l+r<lim) 40 ans=max(ans,l+r); 41 break; 42 } 43 } 44 void dfs(int p) 45 { 46 int i,j; 47 if (p==n-1) 48 { 49 calc(); 50 return; 51 } 52 for (i=1;i<=n+p;i++) 53 for (j=1;j<=n+p;j++) 54 if (i!=j&&tree[i].fat==0&&tree[j].fat==0) 55 { 56 tree[i].fat=tree[j].fat=n+p+1; 57 tree[n+p+1].lson=i; 58 tree[n+p+1].rson=j; 59 tree[n+p+1].wei=tree[i].wei+tree[j].wei; 60 dfs(p+1); 61 tree[i].fat=tree[j].fat=tree[n+p+1].lson=tree[n+p+1].rson=tree[n+p+1].wei=0; 62 } 63 } 64 int main() 65 { 66 int i,j,k,p,q,x,y,z,t; 67 scanf("%d",&t); 68 for (i=1;i<=t;i++) 69 { 70 memset(tree,0,sizeof(tree)); 71 memset(w,0,sizeof(w)); 72 scanf("%lf",&lim); 73 scanf("%d",&n); 74 for (j=1;j<=n;j++) 75 scanf("%lf",&w[j]); 76 for (j=1;j<=n;j++) 77 tree[j].wei=w[j]; 78 ans=-1; 79 dfs(0); 80 if (ans<0) printf("-1\n"); 81 else printf("%.9lf\n",ans); 82 } 83 }
因为数据范围并不大,所以可以枚举。
枚举的方法是枚举二叉树,之后计算每棵树的答案。
枚举的时候,每次选择两个没有父节点的节点连接,n-1次之后即得一棵二叉树。
计算的时候,分别计算两棵子树的宽,再结合本节点天平的宽。
有一个小技巧,由于计算时子程序要返回两个值(最左长度和最右长度),不能直接写成返回值,所以可以用实参引用传值。