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的儿时梦想——机器人篇的更多相关文章

  1. 2016级算法第一次练习赛-E.AlvinZH的儿时回忆——蛙声一片

    864 AlvinZH的儿时回忆----蛙声一片 题目链接:https://buaacoding.cn/problem/865/index 思路 中等题.难点在于理解题意!仔细读题才能弄懂题目规则.整 ...

  2. 2016级算法第一次练习赛-D.AlvinZH的儿时回忆——跳房子

    864 AlvinZH的儿时回忆----跳房子 题目链接:https://buaacoding.cn/problem/864/index 思路 这是一道简单题,但是同样有人想复杂了,DP?大模拟?. ...

  3. 2016级算法第一次练习赛-C.斐波那契进阶

    870 斐波那契进阶 题目链接:https://buaacoding.cn/problem/870/index 思路 通过读题就可以发现这不是一般的求斐波那契数列,所以用数组存下所有的答案是不现实的. ...

  4. 2016级算法第一次练习赛-A.群鸦的盛宴

    858 群鸦的盛宴 题目链接:https://buaacoding.cn/problem/858/index 思路 本题乍一眼看过去,你可能会想到使用一个二维数组A[51][51]来记录从i到j的路线 ...

  5. 2016级算法第一次练习赛-B.朴素的中位数

    朴素的中位数 题目链接:https://buaacoding.cn/problem/846/index 分析 题意很简单,就是给定了两个从小到大排好序的数组,找出这两个数组合起来的数据中的中位数. 方 ...

  6. 2016级算法第二次上机-C.AlvinZH的儿时梦想——坦克篇

    872 AlvinZH的儿时梦想----坦克篇 思路 简单题.仔细看题,题目意在找到直线穿过的矩形数最小,不能从两边穿过.那么我们只要知道每一行矩形之间的空隙位置就可以了. 如果这里用二维数组记住每一 ...

  7. 2016级算法第二次上机-E.AlvinZH的儿时梦想——运动员篇

    862-AlvinZH的儿时梦想--运动员篇 思路 难题. 应该想到,不管给出的数据如何,每一个淘汰的人不会对最终答案产生任何影响,所以每次淘汰就把人除掉就可以了,最后剩下的两个人计算它们从开始到相遇 ...

  8. 2016级算法期末上机-F.中等·AlvinZH's Fight with DDLs II

    1118 AlvinZH's Fight with DDLs II 思路 中等题,贪心. 理解题意,每次攻击中,可以使某个敌人生命值-1,自己生命值减去∑存活敌人总攻击力. 贪心思想,血量少攻击高的要 ...

  9. 2016级算法期末模拟练习赛-F.AlvinZH的青春记忆IV

    1086 AlvinZH的青春记忆IV 思路 难题,动态规划. 这是一道很有意思的题,因为它不仅卡了时间,也卡了空间,而且卡的很妙很迷. 光是理解题意已经有点难度,简化题意:两串数字序列,相等的数字定 ...

随机推荐

  1. 行走于Swift的世界中(转)

    从Swift正式公布到现在,我基本一直在关注和摸索Swift.对于一门新语言来说,开荒阶段的探索自然是激动人心的,但是很多时候,资料的缺失和细节的隐藏也让人着实苦恼.最近几天的感受是,Swift 并不 ...

  2. matrix derivatives

    来源:cs229 stanford Machine Learning Notes

  3. windows 安装 mysql5.7.17

    下载mysql 进入官网:https://www.mysql.com/ 单击[Downloads]选项卡 最下面有个[  MySQL Community Edition (GPL)],单击[Commu ...

  4. NET Framework V4.0.30319

    http://www.microsoft.com/zh-cn/download/details.aspx?id=17718

  5. 优秀前端工程师必备: (总结) 清除原生ios按钮样式

    写移动端的web开发时, 需要清除IOS本身的各种样式: 1.消除ios按钮原生样式, 给按钮加自定义样式: input[type="button"], input[type=&q ...

  6. 在word上写博客直接发到CSDN博客

    目前大部分的博客作者在写博客这件事情上都会遇到以下3个痛点:1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.2.发布到博客或公众号平台 ...

  7. Ubuntu使用tzselect修改时区

    1.命令行运行 sudo tzselect 2.选择洲区(这里选择亚洲Asia) waichung@desktop:~$ sudo tzselect [sudo] password for waich ...

  8. DES加密与解密控制台c++代码

    #include"stdafx.h" #include<stdio.h> #include<string.h> void main() { //声明变量 c ...

  9. SOAP协议初级指南 (一)

    SOAP(Simple Object Access Protocal) 技术有助于实现大量异构程序和平台之间的互操作性,从而使存在的应用能够被广泛的用户所访问.SOAP是把成熟的基于HTTP的WEB技 ...

  10. 2019年第十届蓝桥杯省赛-迷宫(BFS/Excel大法)

    这题用dfs搜不出来,需要使用bfs并记录路径,设置好方向顺序跑就ok 正解类似:POJ-3984 迷宫问题 然而毕竟是暴力杯,我们的原则是代码能省就省(懒癌晚期 于是乎网上便出现了形形色色的题解,笔 ...