路由器安置(Routing)

题目

【问题描述】

  一条街道安装无线网络,需要放置M个路由器。整条街道上一共有N户居民,分布在一条直线上,每一户居民必须被至少一台路由器覆盖到。现在的问题是所有路由器的覆盖半径是一样的,我们希望用覆盖半径尽可能小的路由器来完成任务,因为这样可以节省成本。

【输入数据】

  输入文件第一行包含两个整数M和N,以下N行每行一个整数Hi表示该户居民在街道上相对于某个点的坐标。

【输出数据】

  输出文件仅包含一个数,表示最小的覆盖半径,保留一位小数。

【样例输入】

  2 3

  1

  3

  10

【样例输出】

  1.0

【数据规模】

对于60%的数据,有1 ≤ N, M ≤ 100,-1000 ≤ Hi ≤ 1000;

对于100%的数据,有1 ≤ N, M ≤ 100000,-10000000 ≤ Hi ≤ 10000000。

代码

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<vector>
#define R0(i,n) for(int i=0;i<n;++i)
#define R1(i,n) for(int i=1;i<=n;++i)
#define cl(x,c) memset(x,c,sizeof x)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
template <class T> inline void read(T&x){
    bool f = false; char ch;
    for (ch = getchar(); ch <= 32; ch = getchar());
    if (ch == ‘-‘) f = true, ch = getchar();
    for (x = 0; ch > 32; ch = getchar()) x = x * 10 + ch - ‘0‘;
    if (f) x = -x;
}
template <class T> inline void write(T x){
    if (x < 0) putchar(‘-‘), x = -x;
    if (x < 10)
        putchar(x + ‘0‘);
    else
        write(x / 10), putchar(x % 10 + ‘0‘);
}
void setIO(string t){
    string a=t+".in",b=t+".out";
    freopen(a.c_str(),"r",stdin);
    freopen(b.c_str(),"w",stdout);
}
int S[100005];
int n,m,t;
bool check(int d){
    int cnt=0,lastp=0;
    for(;lastp<n;lastp=upper_bound(S,S+n,S[lastp]+d)-S,cnt++);
    if(cnt<=m)return 1;else return 0;
}
int main(){
    setIO("routing");
    read(m),read(n);
    if(m>=n){puts("0.0");return 0;}
    R0(i,n)read(S[i]);
    sort(S,S+n);
//  unique(S,S+n);
    int r=S[n-1]-S[0],l=0;
    while(l<r){
        int mi=(l+r)>>1;
        if(check(mi))r=mi;
        else l=mi+1;
    }
    printf("%.1lf",(double)l/2.0);
}

感谢wxjlzbcd的脑洞,wfwbz的指导。

二分太神了orz

时间: 2024-07-29 08:30:35

路由器安置(Routing)的相关文章

路由器安置(Routing)

描述 一条街道安装无线网络,需要放置M个路由器.整条街道上一共有N户居民,分布在一条直线上,每一户居民必须被至少一台路由器覆盖到.现在的问题是所有路由器的覆盖半径是一样的,我们希望用覆盖半径尽可能小的路由器来完成任务,因为这样可以节省成本.(1 ≤ N, M ≤ 100000) 分析 首先这种问题可以采用二分答案的方法. 尝试当前路由器覆盖范围能否覆盖所有居民点. 那么这里如果采用二分半径的方法, 会出现实数, 所以采用 wxjlzbcd 的方法, 采用二分直径, 最后实数折半输出. 在尝试答案

路由器安置

一条街道安装WIFI,需要放置M个路由器.整条街道上一共有N户居民,分布在一条直线上,每一户居民必须被至少一台路由器覆盖到.现在的问题是所有路由器的覆盖半径是一样的,我们希望用覆盖半径尽可能小的路由器来完成任务,因为这样可以节省成本. 输入格式: 输入文件第一行包含两个整数M和N,以下N行每行一个整数Hi表示该户居民在街道上相对于某个点的坐标. 输出格式: 输出文件仅包含一个数,表示最小的覆盖半径,保留一位小数. 样例输入: 2 31310 样例输出: 1.0 题解: 二分直径,每次找到没有被覆

总结-分治

分治 分治法是一种效率很高的算法, 往往带有一个log级的复杂度. 1. CDQ分治 CDQ分治可以应用到带有修改操作的题目中, 对操作进行分治, 通过考虑前一半操作对后一半操作的影响达到分治的目的. 应用的条件比较苛刻 BZOJ-1492-货币兑换cash-NOI2007-CDQ分治 优化dp BZOJ-2716-天使玩偶angel-CDQ分治 能这样做还得益于曼哈顿距离的特殊性 BZOJ-2001-city城市建设-HNOI2010-CDQ分治 因为最小生成树Kruskal算法是基于边的算法

H3C 命令大全

进入系统视图 system-view 配置设备名 sysname RouterA 查看FLASH目录下内容 dir 指定下次启动配置文件 startup saved-configuration main.cfg 保存配置 save 重启 reboot #置CONSOLE用户登陆的口令认证 system-view [H3C]user-interface aux 0 [H3C-ui-aux0]authentication-mode password [H3C-ui-aux0]set authenti

协议学习之 vamei博客系列 总结

1. 分层: 物理层(physical layer) 所谓的物理层,是指光纤.电缆或者电磁波等真实存在的物理媒介.这些媒介可以传送物理信号,比如亮度.电压或者振幅.对于数字应用来说,我们只需要两种物理信号来分别表示0和1,比如用高电压表示1,低电压表示0,就构成了简单的物理层协议.针对某种媒介,电脑可以有相应的接口,用来接收物理信号,并解读成为0/1序列. 连接层(link layer) 在连接层,信息以帧(frame)为单位传输.所谓的帧,是一段有限的0/1序列.连接层协议的功能就是识别0/1

微型 Python Web 框架 Bottle

Bottle 是一个非常小巧但高效的微型 Python Web 框架, 它被设计为仅仅只有一个文件的Python模块, 并且除Python标准库外, 它不依赖于任何第三方模块. 路由(Routing): 将请求映射到函数, 可以创建十分优雅的 URL 模板(Templates): Pythonic 并且快速的 Python 内置模板引擎, 同时还支持 mako, jinja2, cheetah 等第三方模板引擎 工具集(Utilites): 快速的读取 form 数据, 上传文件, 访问 coo

IP,ARP,RIP和BGP协议

IP,ARP,RIP和BGP协议 前言 今天还是接着学习计算机网络方面的内容,争取在开学之前先把计算机网络的内容过一遍,JAVA学过一点,但是不精通,能看懂一些简单的代码,仅此而已,大三就只有三门课,数据库,网络,JAVA,好好学,别放弃,最近腰疼的厉害,可能是那天找女朋友的原因,爬山去了,累了个半死,回来就腰疼了.唉,身体跟不上了,身体是革命的本钱,保护好自己的身体,说不定将来买苹果的时候用到了呢... 网络层是实现互联网的最重要的一层.正是网络层面上,各个局域网根据IP协议相互连接,最终构成

协议学习之 vamei博客系列 03 IP接力赛 (IP, ARP, RIP和BGP协议)

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 网络层(network layer)是实现互联网的最重要的一层.正是在网络层面上,各个局域网根据IP协议相互连接,最终构成覆盖全球的Internet.更高层的协议,无论是TCP还是UDP,必须通过网络层的IP数据包(datagram)来传递信息.操作系统也会提供该层的socket,从而允许用户直接操作IP包. IP数据包是符合IP协议的信息(也就是0/1序列),我们后面简称IP数

网络协议总结

信号的传输总要符合一定的协议(protocol).比如说长城上放狼烟,是因为人们已经预先设定好狼烟这个物理信号代表了"敌人入侵"这一抽象信号.这样一个"狼烟=敌人入侵"就是一个简单的协议.协议可以更复杂,比如摩尔斯码(Morse Code),使用短信号和长信号的组合,来代表不同的英文字母.比如SOS(***---***,  *代表短信号,-代表长信号).这样"***= S, ---=O"就是摩尔斯码规定的协议.然而更进一层,人们会知道SOS是求助