例题7-7 UVA 1354 Mobile Computing (搜索+二叉树(类哈夫曼树))

来源:互联网 发布:淘宝的会员管理系统 编辑:程序博客网 时间:2024/06/05 06:29

思路:

想一想就可以知道,一个结点要么有两个儿子,要么没儿子。

那么这就很像哈夫曼树,因此我们可以枚举所有的哈夫曼树(任意枚举两个不同的结点来合并)

然后从根结点开始遍历二叉树,在遍历的同时,来枚举左边 和右边的最大值。

然后R-L 便是这个二叉树的宽度。

更新一下答案即可!

有一个小小的坑把,没注意到:

就是只有一个砝码的时候,答案应该是0 不是-1.

想一想还是很实际的:

只有一个砝码,直接拿个绳子吊起来就行了,题目中说 不考虑砝码的宽度,那么不就是0了吗!!

详细见代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <cmath>#include <cstdlib>#define Siz(x) (int)x.size()using namespace std;const double eps = 1e-10;int dcmp(double a,double b){    if (fabs(a-b) < eps) return 0;    if (a < b) return -1;    return 1;}struct Node{    int v;    int ban;    Node* left;    Node* right;    Node(int v = 0,int ban = 0):v(v),ban(ban){        left = right = NULL;    }};int T, n;double r;double L,R,ans;vector<Node*>v;void dfs2(Node* cur,double dis){    if (cur->left == NULL || cur->right == NULL) return;    int lv = cur->left->v;    int rv = cur->right->v;    double k = rv*1.0/lv;    double a = k/(1+k);    double b = 1.0/(1+k);    double nl = dis - a;    double nr = dis + b;    if (dcmp(L,nl) == 1) L = nl;    if (dcmp(R,nr) == -1) R = nr;    dfs2(cur->left,nl);    dfs2(cur->right,nr);}void dfs(int siz){//    printf("%d\n",siz);    if(siz > 1){        for (int i = 0; i < Siz(v); ++i){            for (int j = 0; j < i; ++j){                if (i != j){//                    printf("%d %d\n",i,j);                    Node* ii = v[i];                    Node* jj = v[j];                    v.erase(v.begin()+i);                    v.erase(v.begin()+j);//                    puts("hahahaha");                    Node* kk = new Node(ii->v + jj->v);                    kk->ban = 1;                    kk->left = new Node();                    kk->right = new Node();                    kk->left = ii;                    kk->right = jj;                    v.push_back(kk);                    dfs(siz-1);                    v.pop_back();                    kk = new Node(ii->v + jj->v);                    kk->ban = 1;                    kk->left = new Node();                    kk->right = new Node();                    kk->left = jj;                    kk->right = ii;                    v.push_back(kk);                    dfs(siz-1);                    v.pop_back();                    if (j >= Siz(v))v.push_back(jj);                    else v.insert(v.begin()+j,jj);                    if (i >= Siz(v))v.push_back(ii);                    else v.insert(v.begin()+i,ii);                }            }        }    }    else {//        puts("ahahah");        Node* root = new Node();        root = *(v.begin());//        printf("%d\n",root->v);        L = 1e18;        R = -1e18;        dfs2(root,0);        double nnr = R-L;        if (dcmp(nnr,r) != 1){//            ans = max(ans,nnr);            if (dcmp(ans,nnr) == -1) ans = nnr;        }    }}int main(){    scanf("%d",&T);    while(T--){        v.clear();        ans = -1e18;        scanf("%lf%d",&r,&n);        for (int i = 0; i < n; ++i) {            int vv;            scanf("%d",&vv);            v.push_back(new Node(vv,0));        }        dfs((int)v.size());        if(n == 1) puts("0"); /// 要格外注意,一个砝码的时候 宽度是0,不是-1.        else if (ans == -1e18) puts("-1");        else printf("%.16f\n",ans);    }    return 0;}


0 0
原创粉丝点击