2016级算法第一次练习赛-F.AlvinZH的儿时梦想——机器人篇
864 AlvinZH的儿时梦想----机器人篇
题目链接:https://buaacoding.cn/problem/868/index
思路
中等题。
判断无限玩耍: \(p\) 的值能够承担的起所有机器的消耗。即比较 \(\sum_{i=1}^{n}a_i\) 与 \(p\) 的大小。
分析
本题有两种解法。
方法一:二分。
即二分枚举最长时间,判断充电器能否支撑此时间所有的耗能,不断缩小时间范围,最后可求得答案。难点在判断函数,比较在当前时间条件下,所有需要充电的机器需要的能量能量总和与充能器提供的能量总和,每次需要遍历一次数组。
方法二:贪心
感谢李析航同学。这道题还有另外一种想法,结构体排序+贪心。
把所有机器在不充电时能用的时间算出来(假设第 \(i\) 个设备能用 \(t_i\) 秒),对时间进行升序排序。让时间短的设备先充电,让尽可能多的机器能用更长的时间,这就是贪心所在。
假设已经保证前m个机器玩耍时间达到 \(t_m\)(即所有机器至少可以玩耍 \(t_m\),初始值为 \(t_0\) ),前m个机器耗能效率 \(A_m=\sum_{i=1}^{m}a_i\) 。现在判断充电能否让玩耍时间延长到 \(t_{m+1}\) ,如果不能,说明答案 \(ans\) 就在 \(t_m\) 和 \(t_{m+1}\) 之间。
由于已经满足前m个机器玩耍时间达到 \(t_m\),为了方便计算,我们假设充电器一直在充电,那么多余的电量设为 \(power\),令 \(x=ans-t_m\),则有 \(power+p_x=A_m\) 。解得 \(x=\frac{power}{A_m-p}\) ,\(ans=x+t_m\)。
还有一种情况,就是已经满足n的机器玩耍时间达到 \(t_n\) 了,这时可以直接计算x就可以得到答案了。
参考代码(解法一)
//
// Created by AlvinZH on 2017/9/30.
// Copyright (c) AlvinZH. All rights reserved.
//
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<cstdlib>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
#include<stack>
#include<queue>
#include<utility>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MaxSize 100005
typedef long long LL;
using namespace std;
int n, p;
int A[MaxSize], B[MaxSize];
bool judge(double t)
{
double inPower = 1.0 * p * t;//可充电总量
double needPower;
for (int i = 0; i < n && inPower > eps; i++) {
needPower = A[i] * t - B[i];//每个机器需要的充电量
if (needPower > eps)
inPower -= needPower;
}
if (inPower < eps) return false;
else return true;
}
int main()
{
while (~scanf("%d %d", &n, &p))
{
LL sumA = 0;
for (int i = 0; i < n; i++) {
scanf("%d %d", &A[i], &B[i]);
sumA += (LL)A[i];
}
if (sumA <= p) printf("Great Robot!\n");
else
{
double ltime = 0.0, rtime = 1e12, mid, ans;
while (rtime - ltime >= eps)
{
mid = (ltime + rtime) / 2.0;
if (judge(mid))
{
ltime = mid;
ans = mid;
}
else rtime = mid;
}
printf("%.3lf\n", ans);
}
}
}
参考代码二
//
// Created by AlvinZH on 2017/9/30.
// Copyright (c) AlvinZH. All rights reserved.
//
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<cstdlib>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
#include<stack>
#include<queue>
#include<utility>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MaxSize 100005
typedef long long LL;
using namespace std;
int n, p, b;
struct Robot {
int a;
double t;
bool operator < (const Robot& r) const {
return t < r.t;
}
};
Robot R[MaxSize];
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("outme.txt", "w", stdout);
while (~scanf("%d %d", &n, &p))
{
LL sumA = 0;
for (int i = 0; i < n; i++) {
scanf("%d %d", &R[i].a, &b);
sumA += (LL)R[i].a;
R[i].t = b * 1.0 / R[i].a;
}
if (sumA <= p) printf("Great Robot!\n");
else
{
sort(R, R + n);
double ans = R[0].t;//最小玩耍时间
double power = R[0].t * p;//初始剩余能量
double timeX;//时间差
double x;//续命时间
sumA = R[0].a;//需要充电机器的总功率
int i = 1;
while(i < n)
{
timeX = R[i].t - ans;
if(sumA > p)//需要充电
{
x = power / (sumA - p);
if(x <= timeX)//无法坚持到R[i]充电
{
printf("%.3f\n", ans + x);
break;
}
}
power = power + timeX * (p - sumA);//计算剩余能量
sumA += R[i].a;
ans = R[i].t;
i++;
}
if(i == n)//全部机器都要充电
{
x = power / (sumA - p);
printf("%.3f\n", ans + x);
}
}
}
}
2016级算法第一次练习赛-F.AlvinZH的儿时梦想——机器人篇的更多相关文章
- 2016级算法第一次练习赛-E.AlvinZH的儿时回忆——蛙声一片
864 AlvinZH的儿时回忆----蛙声一片 题目链接:https://buaacoding.cn/problem/865/index 思路 中等题.难点在于理解题意!仔细读题才能弄懂题目规则.整 ...
- 2016级算法第一次练习赛-D.AlvinZH的儿时回忆——跳房子
864 AlvinZH的儿时回忆----跳房子 题目链接:https://buaacoding.cn/problem/864/index 思路 这是一道简单题,但是同样有人想复杂了,DP?大模拟?. ...
- 2016级算法第一次练习赛-C.斐波那契进阶
870 斐波那契进阶 题目链接:https://buaacoding.cn/problem/870/index 思路 通过读题就可以发现这不是一般的求斐波那契数列,所以用数组存下所有的答案是不现实的. ...
- 2016级算法第一次练习赛-A.群鸦的盛宴
858 群鸦的盛宴 题目链接:https://buaacoding.cn/problem/858/index 思路 本题乍一眼看过去,你可能会想到使用一个二维数组A[51][51]来记录从i到j的路线 ...
- 2016级算法第一次练习赛-B.朴素的中位数
朴素的中位数 题目链接:https://buaacoding.cn/problem/846/index 分析 题意很简单,就是给定了两个从小到大排好序的数组,找出这两个数组合起来的数据中的中位数. 方 ...
- 2016级算法第二次上机-C.AlvinZH的儿时梦想——坦克篇
872 AlvinZH的儿时梦想----坦克篇 思路 简单题.仔细看题,题目意在找到直线穿过的矩形数最小,不能从两边穿过.那么我们只要知道每一行矩形之间的空隙位置就可以了. 如果这里用二维数组记住每一 ...
- 2016级算法第二次上机-E.AlvinZH的儿时梦想——运动员篇
862-AlvinZH的儿时梦想--运动员篇 思路 难题. 应该想到,不管给出的数据如何,每一个淘汰的人不会对最终答案产生任何影响,所以每次淘汰就把人除掉就可以了,最后剩下的两个人计算它们从开始到相遇 ...
- 2016级算法期末上机-F.中等·AlvinZH's Fight with DDLs II
1118 AlvinZH's Fight with DDLs II 思路 中等题,贪心. 理解题意,每次攻击中,可以使某个敌人生命值-1,自己生命值减去∑存活敌人总攻击力. 贪心思想,血量少攻击高的要 ...
- 2016级算法期末模拟练习赛-F.AlvinZH的青春记忆IV
1086 AlvinZH的青春记忆IV 思路 难题,动态规划. 这是一道很有意思的题,因为它不仅卡了时间,也卡了空间,而且卡的很妙很迷. 光是理解题意已经有点难度,简化题意:两串数字序列,相等的数字定 ...
随机推荐
- Emgu CV的配置以及在VS 2012中进行图像处理的步骤和实例
说明: 1.所使用的Emgu CV是目前的最新版本3.1.0,下载链接为:https://sourceforge.net/projects/emgucv/files/emgucv/3.1.0/(我选的 ...
- vmware centos7 静态ip设置
最近在学习linux环境部署~~~~ 首先,将网络适配设置成为桥接模式 查看本机IP地址,ipconfig,记住ipv4地址和默认网关地址,等会配置的时候要用 启动Centos,进入终端模式,设置IP ...
- Django框架请求生命周期
先看一张图吧! 1.请求生命周期 - wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask.Django) - 中间件,帮助我们对请求进行校 ...
- HBase预分区方法
(what)什么是预分区? HBase表在刚刚被创建时,只有1个分区(region),当一个region过大(达到hbase.hregion.max.filesize属性中定义的阈值,默认10GB)时 ...
- Qt之生成pdf(转)
Qt中如何让图片.文本.HTML或者其他形式的内容生成pdf呢?主要利用QPrinter来实现,QPrinter不止可以操作打印机来打印纸张文件,并且可以将文件保存至磁盘,存储为pdf格式的文件. ...
- ASP.NET MVC WebApi接口授权验证
对于很任何多开发者来说,不管是使用任何一种框架,或者是使用任何一种语言,都要使用面向接口编程.使用面向接口编程的时候,那么就会有很多的权限验证,用户验证等等. 特别是对于一些系统来说,别人想要对接你的 ...
- 一个简单的编译tex的Makefile
tex编译成pdf通常要经过以下步骤:tex-->dvi-->ps-->pdf.如果修改了tex文件想看一下效果,就要把命令重新敲一遍.虽然就几行命令,反复敲还是很烦人的.最直接的办 ...
- 解剖JavaScript中的null和undefined【转】
在JavaScript开发中,被人问到:null与undefined到底有啥区别? 一时间不好回答,特别是undefined,因为这涉及到undefined的实现原理.于是,细想之后,写下本文,请各位 ...
- Java中的Type
Type是Java 编程语言中所有类型的公共高级接口(官方解释),也就是Java中所有类型的“爹”:其中,“所有类型”的描述尤为值得关注.它并不是我们平常工作中经常使用的 int.String.Lis ...
- 第二章第一个项目——package.json
在其中写版本好的时候, { "name": "chatroom", "version": "0.0.1", " ...