UVa 1354 天平难题
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 天平难题的更多相关文章
- UVa 1354 天平难题 (枚举二叉树)
题意: 分析: 其实刚看到这题的时候觉得很难, 以至于结束了第七章然后去做了一遍第六章树的部分.现在再做这题觉得思路并不是太难,因为总共就只有六个结点,那么只要枚举二叉树然后算出天平然后再从叶子往上推 ...
- UVa 1354 天平难题 Mobile Computing
整个题考虑起来 最主要要计算的状态 是树的状态 于是要计算出所有可能挂坠可能组成的树的所有形态 tree 用于保存这些状态 考虑不要重复计算,有一个vis 数组 预处理可以先计算出一棵树的重量,简化计 ...
- 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 ...
- uva 1354 Mobile Computing ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5
- UVa 839 天平
原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- Uva 1354 Mobile Computing
题目链接 题意: 在一个宽为r 的房间里, 有s个砝码, 每个天平的一端要么挂砝码, 要么挂另一个天平, 并且每个天平要保持平衡. 求使得所有砝码都放在天平上, 且总宽度不超过房间宽度的最大值. 思路 ...
- uva1354 天平难题 【位枚举子集】||【huffman树】
题目链接:https://vjudge.net/contest/210334#problem/G 转载于:https://blog.csdn.net/todobe/article/details/54 ...
- UVa 1354 枚举子集 Mobile Computing
只要枚举左右两个子天平砝码的集合,我们就能算出左右两个悬挂点到根悬挂点的距离. 但是题中要求找尽量宽的天平但是不能超过房间的宽度,想不到要怎样记录结果. 参考别人代码,用了一个结构体的vector,保 ...
- Uva 839天平(二叉树dfs, 递归建树)
题意: 给定一个天平长度 输入格式为 wl dl wr dr 分别代表天平左边长度,左边重量, 右边长度, 右边重量. 如果重量为0, 说明下面还有一个天平, 递归给出. 样例输入:10 2 0 40 ...
随机推荐
- 从jvm来看,scala中的@究竟是个什么鬼?@模式匹配符号(scala 词法分析 语法分析常用)
从jvm来看,scala中的@究竟是个什么鬼? 我也是初步尝试来看jvm的类文件,又是初次来分析@,如不对的地方,请各位指正! 先看一下@ 是个什么? object TestScala { def m ...
- Kettle定时抽取两个库中的两个表到目标库SYS_OPLOG表
A库a表(红色为抽取字段): 关联用户表: B库b表(红色为抽取字段): 关联用户表 C目标库SYS_OPLOG表(c表) 利用kettle抽取A库a表(具体名称见上图),B库b表的上面红色框起来 ...
- php中&运算符的理解与使用
php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容. 变量的引用 PHP 的引用允许你用两个变量来指向同一个内容 例一: < ...
- ComBSTR的使用
用 CComBSTR 进行编程 Visual Studio .NET 2003 3(共 3)对本文的评价是有帮助 - 评价此主题 ATL 类 CComBSTR 提供对 BSTR 数据类型的包装 ...
- VMware Coding Challenge: The Heist
类似BackpackII问题 static int maximize_loot(int[] gold, int[] silver) { int[][] res = new int[gold.lengt ...
- Lintcode: Find Peak Element
There is an integer array which has the following features: * The numbers in adjacent positions are ...
- js数组之可变函数
在js的数组中有两个方法为数组添加元素:1.push();2.unshift(),push函数是将元素添加到数组的末尾,现在不用说大家估计也能猜出来,unshift这个函数就是把元素添加到数组的开头的 ...
- zoj3814
这题说的是给了一个数在longlong范围内 然后求出小于这个数的最大的回文,枚举每位减去1后 , 他后面的位置上全部都置为9,然后在枚举每个前半部分,然后贪心取得这个数的最大值,贪心的时候写错了,错 ...
- .NET 和 .NET框架概览
什么是.NET .NET是为简化在第三代因特网的分布式环境下的应用程序的开发,基于开放互联网标准和协议之上,实现异质语言和平台高度交互性而构建的新一代计算和通信平台.其主要由三部分构成:.NET框架. ...
- Keepalived 安装
Keepalived 安装安装环境 keepalived-1.2.18.tar.gz VM虚拟机redhat6.5-x64:192.168.1.201 Xshell4 部署方案 201部署 安装步骤 ...