博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj3231
阅读量:6327 次
发布时间:2019-06-22

本文共 2954 字,大约阅读时间需要 9 分钟。

简单模拟,题意描述不清晰,我来仔细描述一下,flashget在下载一些文件,每个文件有一个初始大小,初始速度,最大速度。当一个文件下载结束后,他的速度(占用的带宽)会平均分配给别的任务(各文件的速度增加值相同),假设我们要把速度x分配给a个文件,那么就要给每个文件分配x/a的速度,前提条件是分配后该文件的速度不超过其最大速度。若超过了则不能给他分配这么多,只让它达到其最大速度即可。这样一来我们的下载速度就会有剩余,因为受到最大速度的限制,有些文件并没有被分配到x/a这么多的速度。对于剩余的速度怎么处理呢?就是除去那几个已经到达最大速度的文件,其余文件按照刚才的方法再分配一次剩余速度。模拟即可。这题精度很难控制,我开始试着用先将所有到达最大速度的进程先处理,最后再计算平均值的方法,居然是错的,理论上这种做法比上述做法精度高。

View Code
#include 
#include
#include
#include
#include
using namespace std;#define maxn 105struct Elem{ double size, speed, max_speed;} elem[maxn];int n, m;double time_left[maxn];bool finished[maxn];double ans[maxn];double reached[maxn];int task_left;void input(){ scanf("%d", &m); for (int i = 0; i < n; i++) scanf("%lf%lf%lf", &elem[i].size, &elem[i].speed, &elem[i].max_speed);}void cal_time(){ for (int i = 0; i < n; i++) if (!finished[i]) time_left[i] = elem[i].size / elem[i].speed;}void size_reduce(double min_time){ for (int i = 0; i < n; i++) if (!finished[i]) elem[i].size -= min_time * elem[i].speed;}int get_min(){ int ret = 0; while (finished[ret]) ret++; for (int i = ret + 1; i < n; i++) if (!finished[i] && time_left[i] < time_left[ret]) ret = i; return ret;}void distribute(double bandwidth){ double band_left = bandwidth; int num = 0; for (int i = 0; i < n; i++) if (!finished[i] && !reached[i]) num++; if (num == 0) return; double average; while (band_left > 0) { average = band_left / num; bool did = false; for (int i = 0; i < n; i++) { if (finished[i] || reached[i]) continue; did = true; if (elem[i].max_speed - elem[i].speed < average) { band_left -= elem[i].max_speed - elem[i].speed; elem[i].speed = elem[i].max_speed; reached[i] = true; num--; }else { band_left -= average; elem[i].speed += average; } } if (!did) break; }}void work(){ memset(finished, 0, sizeof(finished)); memset(reached, 0, sizeof(reached)); double now_time = 0; task_left = n; while (task_left > 0) { cal_time(); int next_task = get_min(); finished[next_task] = true; task_left--; double bandwidth = elem[next_task].speed; double min_time = time_left[next_task]; size_reduce(min_time); now_time += min_time; ans[next_task] = now_time; distribute(bandwidth); }}int main(){ //freopen("t.txt", "r", stdin); int t = 0; while (scanf("%d", &n), n) { t++; printf("Case %d:\n", t); input(); work(); for (int i = 0; i < n; i++) printf("NO%d:%.3fs\n", i + 1, ans[i]); } return 0;}

 

转载地址:http://iqgaa.baihongyu.com/

你可能感兴趣的文章
NetBackup下ORACLE恢复测试方案实例解析
查看>>
【有奖征文】“失业”程序员的苦辣酸甜
查看>>
nagios监控web/mysql多角度实战分享(一)
查看>>
SCOM 2012系列⑦即时消息通知上
查看>>
IE9是如何被FireFox4超越全球市场份额的?
查看>>
linux bunzip2命令
查看>>
敏捷个人:通过实践TOGAF来思考如何学习并应用新的方法?
查看>>
Android系统的开机画面显示过程分析(6)
查看>>
vivo Hi-Fi+QQ音乐 数字音乐市场的一剂良方
查看>>
Cocos2d-x 3.2 异步动态加载 -- 保卫萝卜开发总结
查看>>
聚焦触宝反侵权事件:中国创业者用什么护航海外市场大门
查看>>
AOP技术基础
查看>>
Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析(2)
查看>>
Lync 小技巧-5-当前已暂停共享
查看>>
无线802.11n 2.4G与5G性能测试
查看>>
子域名信息收集攻略
查看>>
[Android]开发数独游戏思路分析过程
查看>>
SpreadJS 类Excel表格控件 - V12 新特性详解
查看>>
理解并取证:IPv6与IPv4在报文结构上的区别
查看>>
小白该如何学习Linux操作系统(2)
查看>>