[2018.04.17][水][日志][8][#195][路由器安置][Wi-Fi][->][二分/递增][网速堪忧x1]

[背景]

    抓紧时间写完!

    今天耗费VHOS心力最多的是这道虚伪的题目,首先必须要吐槽一下:为什么WIFI设置这么坑!!!!

    好的,由于我们上的是分治,所以我优先选择了二分来做这道题,同时给出周神的递增版本。

[题目]

题目描述
一条街道安装WIFI,需要放置M个路由器。整条街道上一共有N户居民,分布在一条直线上,每一户居民必须被至少一台路由器覆盖到。现在的问题是所有路由器的覆盖半径是一样的,我们希望用覆盖半径尽可能小的路由器来完成任务,因为这样可以节省成本。
输入格式
输入文件第一行包含两个整数M和N,以下N行每行一个整数Hi表示该户居民在街道上相对于某个点的坐标。 
输出格式
输出文件仅包含一个数,表示最小的覆盖半径,保留一位小数。
样例数据
input
2 3
1
3
10
output
1.0
数据规模与约定
时间限制:1s
1s
空间限制:256MB
256MB
注释

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

[二分的分析]

很显然这道题要枚举最合适的路由器范围直径(然后除以二出答案)

而枚举的任务就交给枚举的代码了;


以上是程序的准备模块


很好,二分的主体完成了,现在只要判断这个直径值成不成立就行了;

虚伪虚伪虚伪虚伪,严重怀疑网络稳定性


[code]

[二分]

#include<bits/stdc++.h>

const int maxn=1<<17;

int lc[maxn]={};
int home=0,max_wifi=0;

int ip(void)
{
	int sign=1,num=0;
	char c=getchar();
	for(;c<'0'||c>'9';c=getchar())
		 if(c=='-')
			sign=-1;
	for(;c>='0'&&c<='9';c=getchar())
		num=(num<<1)+(num<<3)+c-'0';
	return num*sign;
}

bool check(int size)
{
	int wifi=0;
	int left=1,right=1;
	
	while(right<=home)
	{
		while(lc[right]-lc[left]<=size&&right<=home)
			right++;
		
		left=right;
		wifi++;
	}
	
	if(wifi<=max_wifi)
		return true;
	else
		return false;
}

int main(void)
{
	max_wifi=ip();
	home=ip();
	
	for(int i=1;i<=home;i++)
	{
		lc[i]=ip();
	}
	std::sort(lc+1,lc+home+1);
	
	int left=-1<<22;
	int right=1<<22;
	int mid=0;
	while(left+1<right)
	{
		mid=(left+right)>>1;
		if(check(mid))
			right=mid;
		else
			left=mid;
	}
	
	if(check(left))
		printf("%.1f",left*1.0/2);
	else
		printf("%.1f",right*1.0/2);
	return 0;
}

[递增]{周神提供}

#include<bits/stdc++.h>
using namespace std;
    int a[1002003],n,m;

#define C getchar()-48
inline int read()
{
    int s=0,t=1,k=C;
  for (;k>9||k<0;k=C) if (k==-3) t=-1;
  for (;k>=0&&k<=9;k=C) s=(s<<1)+(s<<3)+k;
  return s*t;
}

inline int che(int k)
{
  int t=0,l=1,r=1;
  while (r<=n)
	{
	  while (a[r]-a[l]<=k&&r<=n) r++;
	  l=r,++t;
	}
  if (t<=m) return 1;
  return 0;
}

int main(void)
{
  cin>>m>>n;
  for (int i=n;i;--i)
	a[i]=read();
  sort(a+1,a+n+1);
    int k=a[n]-a[1];
  for (int i=log2(k);i>=0;--i)
    if (k-(1<<i)>0&&che(k-(1<<i))) k-=1<<i;
  printf("%.1f",k*1.0/2);
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34840328/article/details/80070925
今日推荐