洛谷P1984 SDOI2008烧水问题
P1984 [SDOI2008]烧水问题
- 186通过
- 438提交
- 题目提供者lych
- 标签数论(数学相关)模拟各省省选
- 难度普及+/提高
提交该题 讨论 题解 记录
最新讨论
- 求助!
- 也是醉了。。。
- 题目有问题
- 这个不是SDOI的题吧...
- 这是什么????
题目描述
把总质量为1kg的水分装在n个杯子里,每杯水的质量均为(1/n)kg,初始温度均为0℃。现需要把每一杯水都烧开。我们可以对任意一杯水进行加热。把一杯水的温度升高t℃所需的能量为(4200*t/n)J,其中,“J”是能量单位“焦耳”。如果一旦某杯水的温度达到100℃,那么这杯水的温度就不能再继续升高,此时我们认为这杯水已经被烧开。显然地,如果直接把水一杯一杯地烧开,所需的总能量为(4200*100)J。
在烧水的过程中,我们随时可以在两杯温度不同的水之间进行热传递操作。热量只能从温度较高的那杯水传递到温度较低的那杯水。由于两杯水的质量相同,所以进行热传递操作之后,原来温度较高的那杯水所降低的温度总是等于原来温度较低的那杯水所升高的温度。
一旦两杯水的温度相同,热传递立刻停止。
为了把问题简化,我们假设:
1、没有进行加热或热传递操作时,水的温度不会变化。
2、加热时所花费的能量全部被水吸收,杯子不吸收能量。
3、热传递总是隔着杯子进行,n杯水永远不会互相混合。
4、热传递符合能量守恒,而且没有任何的热量损耗。
在这个问题里,只要求把每杯水都至少烧开一遍就可以了,而不要求最终每杯水的温度都是100℃。我们可以用如下操作把两杯水烧开:先把一杯水加热到100℃,花费能量(4200*100/2)J,然后两杯水进行热传递,直到它们的温度都变成50℃为止,最后把原来没有加热到100℃的那杯水加热到100℃,花费能量(4200*50/2)J,此时两杯水都被烧开过了,当前温度一杯100℃,一杯50℃,花费的总能量为(4200*75)J,比直接烧开所需的(4200*100)J少花费了25%的能量。
你的任务是设计一个最佳的操作方案使得n杯水都至少被烧开一遍所需的总能量最少。
输入输出格式
输入格式:
输入文件只有一个数n。
输出格式:
输出n杯水都至少被烧开一遍所需的最少的总能量,单位为J,四舍五入到小数点后两位。
输入输出样例
2
315000.00
说明
1≤n≤50000
分析:一个很容易想到的思路就是把每杯水能传递的热量都给传递,考虑第i杯水,如果想要到100℃,那么从第1杯到第i-1杯水能给它热传递就热传递,这样可以发现从1到i-1杯水的温度是递增的,所以结果一定是最优的,然后把这个暴力打上去后超时......
那么就要用一些特殊的方法了,注意到题目只给出了一个数n,而要求输出一堆东西,那么很显然,不是递推就是数学公式,加上数据有那么大,可以确定为数学公式,然后发现这个公式我推不出来,那么这个时候就要找规律了,手动模拟一下.
为了方便起见,每杯水升1℃需要消耗1J,假设有4杯水,第一杯水需要消耗100J的能量,第二杯水需要消耗50J的能量,第三杯水需要消耗37.5J的能量,第四杯水需要消耗31.25J的能量,设第i杯水花费的能量为costi,那么cost2 = (1/2)cost1,cost3 = (3/4)cost2,cost4 = (5/6)cost3,然后发现规律,对于第i杯水而言,消耗的能量=costi-1 * (2*i - 1)/(2*i),然后一个循环就搞定了.数学规律有时候也要靠找规律找到啊!
暴力程序(20分):
#include <cstdio> double t[50010];int main() {int n; scanf("%d", &n);double cur = 420000.00 / n, tot = 0;int j;t[1] = cur;for (int i = 1; i <= n; i++){double temp = 0;for (j = 1; j < i; j++){temp = (t[j] - t[i]) / 2;t[j] -= temp;t[i] += temp;}tot += cur - t[i];t[i] = cur;}printf("%.2lf\n", tot + cur);return 0; }
正解:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm>using namespace std;int n; double cost, ans;int main() {scanf("%d", &n);cost = 420000.00 / n;for (int i = 1; i < n; i++){ans += cost;cost *= (double)(2 * i - 1) / (double)(2 * i);}printf("%.2lf\n", ans + cost); //计算ans的时候没有加上最后一个return 0; }
转载于:https://www.cnblogs.com/zbtrs/p/5831475.html
洛谷P1984 SDOI2008烧水问题相关推荐
- 洛谷 P2463 [SDOI2008]Sandy的卡片 解题报告
P2463 [SDOI2008]Sandy的卡片 题意 给\(n(\le 1000)\)串,定义两个串相等为"长度相同,且一个串每个数加某个数与另一个串完全相同",求所有串的最长公 ...
- P1984 [SDOI2008]烧水问题
luogu 传送门 这题好生厉害! 如果n再小一点的话,这题是个贪心.我们把烧到过100度的水能进行热传导就进行热传导,一直向后进行. 这种做法是O(n^2)的,显然过不了. 然后注意到,这题肯定有规 ...
- 洛谷P2158 [SDOI2008]仪仗队
题目描述 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图 ...
- 洛谷P2463 [SDOI2008]Sandy的卡片(后缀数组SA + 差分 + 二分答案)
题目链接:https://www.luogu.org/problem/P2463 [题意] 求出N个串中都出现的相同子串的最长长度,相同子串的定义如题:所有元素加上一个数变成另一个,则这两个串相同,可 ...
- 洛谷P2147[SDOI2008]洞穴勘测
题目 LCT,或者并查集水过. 首先并查集这道题不能路径压缩,因为路径压缩是为了用牺牲一些信息的方法来加快速度,可是这道题我们需要这个信息,所以不能路径压缩. 剩下的操作就只剩下了暴力并查集,而每次查 ...
- 洛谷 - 试炼场(全部题目备份)
整理的算法模板合集: ACM模板 目录 1.新手村 1 - 1 洛谷的第一个任务 1 - 2 顺序与分支 1 - 3 循环!循环!循环! 1 - 4 数组 1 - 5 简单字符串 1 - 6 过程函数 ...
- 洛谷-题解 P2672 【推销员】
独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...
- 洛谷 P1142 轰炸
洛谷 P1142 轰炸 题目描述 "我该怎么办?"飞行员klux向你求助. 事实上,klux面对的是一个很简单的问题,但是他实在太菜了. klux要想轰炸某个区域内的一些地方,它们 ...
- 洛谷 P1387 最大正方形
P1387 最大正方形 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=10 ...
最新文章
- java jsp转html_JSP页面转换为HTML页面,动态转静态
- 公益合种樟子松/新树专车3天领证
- Python计算医疗数据训练集、测试集的对应的临床特征:训练集(测试集)的阴性和阳性的样本个数、连续变量的均值(标准差)以及训练测试集阳性阴性的p值、离散变量的分类统计、比率、训练测试集阳性阴性的p值
- Flash学习笔记(01)
- JavaScript 表单编程
- 主板和cpu搭配表_GTX1650显卡搭配知识:GTX1650配什么CPU和主板及多大电源?
- Java 并发编程系列之带你了解多线程
- idea找不到Hide empty Middle Packages???
- 程序员修神之路--打通Docker镜像发布容器运行流程
- 看脸色知体内各积毒 有效清洁内脏妙方
- 计算系统和计算机系统是同一个概念嘛,计算机操作系统的基本概念
- Atitit 项目管理(5)----------后勤管理与工具链支持管理
- C语言丨筛法求素数(质数)
- 黑客帝国产业链调查:熊猫烧香作者一年赚千万
- 陈丹琦“简单到令人沮丧”的屠榜之作:关系抽取新SOTA!
- matlab usb采集,求助MATLAB是否支持USB数据采集卡
- 游戏反外挂的难点和破局之路
- 360Wonder监控系统,设计和开发经验之谈
- 软件的「向前兼容」和「向后兼容」
- 携程PMO封面人物 | 关群 AUG Meetup