https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4100

题意:给出房间的宽度和挂坠的重量,设计一个尽量宽的天平,挂着所有挂坠,当然不可以超过房间宽度。

这道题我真的是一点想法都没有,也不知道怎么去枚举二叉树好,下面都是参考别人的代码,我自己也思考了很久,总算是搞清楚了,用二进制法来枚举子集,太妙了。

这样一来也就可以不用特别考虑右子树的左子树比左子树的左子树长的情况了。

 #include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std; const int maxn = << ;
int s;
double r;
int vis[maxn];
double sum[maxn];
double w[]; struct Node
{
double l, r;
Node(double x, double y) { l = x; r = y; }
Node() {}
}; vector<Node> node[maxn]; int bitcount(int x)
{
if (x == ) return ;
return bitcount(x / ) + (x & );
} void dfs(int k)
{
if (vis[k]) return; //如果该状态已访问,则直接返回
vis[k] = ;
if (bitcount(k) == ) //如果此时只有一个1,则只有一个子集,说明是叶子节点,天平左右都为0
{
node[k].push_back(Node(, ));
return;
}
for (int l = (k - )&k; l > ; l = (l - )&k) //二进制法枚举左右子集
{
int r = k^l; //求出补集,即右子集
dfs(l); //继续枚举左子集
dfs(r); //继续枚举右子集
for (int i = ; i < node[l].size(); i++)
{
for (int j = ; j < node[r].size(); j++)
{
double ll = min(-sum[r] / (sum[l] + sum[r]) + node[l][i].l, sum[l] / (sum[l] + sum[r]) + node[r][j].l);
double rr = max(sum[l] / (sum[l] + sum[r]) + node[r][j].r, -sum[r] / (sum[l] + sum[r]) + node[l][i].r);
node[k].push_back(Node(ll, rr)); //将该节点左右臂长加入数组
}
}
}
} void solve()
{
double width = -;
int k = ( << s) - ;
dfs(k);
for (int i = ; i < node[k].size();i++)
if (node[k][i].r - node[k][i].l<r && node[k][i].r - node[k][i].l>width)
width = node[k][i].r - node[k][i].l;
if (width == -) cout << "-1" << endl;
else printf("%.16lf\n", width);
} int main()
{
int n;
cin >> n;
while (n--)
{
memset(vis, , sizeof(vis));
memset(sum, , sizeof(sum));
memset(node, , sizeof(node));
cin >> r >> s;
for (int i = ; i < s; i++)
{
cin >> w[i];
}
for (int i = ; i < ( << s); i++) //计算出每个子集的总重量
{
for (int j = ; j < s; j++)
{
if (i & ( << j))
sum[i] += w[j];
}
}
solve();
}
return ;
}

UVa 1354 天平难题的更多相关文章

  1. UVa 1354 天平难题 (枚举二叉树)

    题意: 分析: 其实刚看到这题的时候觉得很难, 以至于结束了第七章然后去做了一遍第六章树的部分.现在再做这题觉得思路并不是太难,因为总共就只有六个结点,那么只要枚举二叉树然后算出天平然后再从叶子往上推 ...

  2. UVa 1354 天平难题 Mobile Computing

    整个题考虑起来 最主要要计算的状态 是树的状态 于是要计算出所有可能挂坠可能组成的树的所有形态 tree 用于保存这些状态 考虑不要重复计算,有一个vis 数组 预处理可以先计算出一棵树的重量,简化计 ...

  3. UVa 1354 Mobile Computing | GOJ 1320 不加修饰的天平问题 (例题 7-7)

    传送门1(UVa): https://uva.onlinejudge.org/external/13/1354.pdf 传送门2(GOJ): http://acm.gdufe.edu.cn/Probl ...

  4. uva 1354 Mobile Computing ——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5

  5. UVa 839 天平

    原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  6. Uva 1354 Mobile Computing

    题目链接 题意: 在一个宽为r 的房间里, 有s个砝码, 每个天平的一端要么挂砝码, 要么挂另一个天平, 并且每个天平要保持平衡. 求使得所有砝码都放在天平上, 且总宽度不超过房间宽度的最大值. 思路 ...

  7. uva1354 天平难题 【位枚举子集】||【huffman树】

    题目链接:https://vjudge.net/contest/210334#problem/G 转载于:https://blog.csdn.net/todobe/article/details/54 ...

  8. UVa 1354 枚举子集 Mobile Computing

    只要枚举左右两个子天平砝码的集合,我们就能算出左右两个悬挂点到根悬挂点的距离. 但是题中要求找尽量宽的天平但是不能超过房间的宽度,想不到要怎样记录结果. 参考别人代码,用了一个结构体的vector,保 ...

  9. Uva 839天平(二叉树dfs, 递归建树)

    题意: 给定一个天平长度 输入格式为 wl dl wr dr 分别代表天平左边长度,左边重量, 右边长度, 右边重量. 如果重量为0, 说明下面还有一个天平, 递归给出. 样例输入:10 2 0 40 ...

随机推荐

  1. 007-ant design 对象属性赋值,双向绑定

    1.state对象属性赋值 设对象为 state={ datavalue:{ id:'', name:'', }, } 修改对象属性为: SetName=(e)=>{ let val=e.tar ...

  2. GOLANG错误处理最佳方案errors wrap, Defer, Panic, and Recover

    Simple error handling primitives:        https://github.com/pkg/errors Defer, Panic, and Recover:    ...

  3. [py]戏说python面向对象细节

    面向对象圣经 认识面向对象 什么是面向对象? 有什么实在的好处? 被坑了这么多年,没弄清楚和面向过程有啥切身的区分 我以为这都是大学老师的错. 没把我们启蒙好. 这么多年深受其害. 总结起来三个字: ...

  4. testng入门教程11 TestNG运行JUnit测试

    现在,您已经了解了TestNG和它的各种测试,如果现在担心如何重构现有的JUnit代码,那就没有必要,使用TestNG提供了一种方法,从JUnit和TestNG按照自己的节奏.也可以使用TestNG执 ...

  5. iOS 自定义日志输出

    在做iOS开发过程中,我们经常需要输出日志来查看某些数据是否打印出来,或者查看查个类是否被调用了. 系统默认的是NSLog(@"xxxx %d",1) ,但如果该APP要发布到商店 ...

  6. 浅谈Java中的==和equals

    引言 最近在看TIJ,看到==和equals相关内容,今天就来简单的总结下. 关系操作符== 书中对关系操作符的描述是这样的:"关系操作符生成的是一个boolean结果,它们计算的是操作数的 ...

  7. 怎样在div中添加图片或设置颜色

    1.插入图片<div><img src="图片地址" /></div>2.图片做背景<div style="background ...

  8. linux make configure make

    开放源码:就是程序代码,写给人类看的程序语言,但机器并不认识,所以无法执行: 编译程序:将程序代码转译成为机器看得懂的语言,就类似编译者的角色: 可执行文件:经过编译程序变成二进制后机器看得懂所以可以 ...

  9. 26最短路径之Floyd算法

    Floyd算法 思想:将n个顶点的图G“分成”很多子图 每对顶点vi和vj对应子图Gij(i=0,1,…,n-1和j=0,1,…,n-1) 每对顶点vi和vj都保留一条顶点限于子图Gij中的最短路径P ...

  10. Git 常用的命令

    基本内容: 工作区:就是你在电脑里能看到的目录. 暂存区:英文叫stage, 或index.一般存放在"git目录"下的index文件(.git/index)中,所以我们把暂存区有 ...