【二分答案】【中位数】codeforces 394 bun
bun
Description
因为体育老师很喜欢等差数列,所以他要求学生们站队必须按身高站成等差数列。
但是有些班级的学生无论如何也无法排成等差数列,于是体育老师从食堂买来了两种神
奇的面包。吃一个第一种面包可以使身高增 1,吃一个第二种面包可以使身高减 1。
你的任务是,对于某个班级,帮助老师安排哪些同学食用多少面包。考虑到学生的身体
健康,体育老师希望吃面包最多的学生吃的面包数量尽量少。
Input Format
第一行一个正整数 n,表示学生的数目。
第二行是长度为 n 的整数序列 a, a[i]表示第 i 个学生的身高。由于体育老师使用的奇怪
的身高单位,学生身高可能是负数。可以打乱顺序重新排列。
Output Format
第一行一个整数,表示吃面包最多的学生吃的面包数量。
第二行两个整数,分别表示等差数列的首项和公差,公差不能为负。
如果有多解,输出公差最小的方案。如果还有多解,输出首项最小的方案。
Sample Input (1)
5
-3 -4 -2 -3 3
Sample Output (1)
2
-3 1
Sample Input (2)
5
2 -3 -1 -4 3
第 8 页 共 8 页
Sample Output (2)
1
-4 2
Hint
对于 30%的数据,n<=100,a[i]的绝对值<=1000。
对于 60%的数据,n<=1000,a[i]的绝对值<=100000。
对于 100%的数据,n<=100000,a[i]的绝对值<=1000000。
<法一>记f1为当前需要吃的增高面包的最大的量,f2为当前需要吃的减低面包最大的量。
考虑暴力的情况,枚举公差d,我们可以通过计算f1、f2,再取中位数的方式得到当前的最优首项。
我们把每个d对应的f1、f2打出表来,就可以发现,f1单调递减,f2单调递增,它们两个相交的位置就是答案,二分即可(怕写错,写了分块答案)。
<法二>orz faebdc,我们在枚举d的时候,易发现,d最大不会超过4*max(a[i])/n,否则还不如把a全变0更优,因此暴力就好啦~
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 100001
int n,a[N],ans=2147483647,b[N],f1,f2,D,X0;
int main()
{
scanf("%d",&n);
if(n<=1000){
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
sort(a+1,a+n+1);
int lim=30000000/n;
f1=f2=0;
for(int i=1;i<=n;++i)
{
b[i]=a[1]-a[i];
if(b[i]>0) f2=max(f2,b[i]);
else f1=max(f1,-b[i]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=0;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
for(int d=1;d<=lim;++d)
{
f1=f2=0;
for(int i=2;i<=n;++i)
{
b[i]+=(i-1);
if(b[i]>0) f2=max(f2,b[i]);
else f1=max(f1,-b[i]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=d;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
}
printf("%d\n%d %d\n",ans,X0,D);
return 0;
}
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
sort(a+1,a+n+1);
f1=f2=0;
for(int i=1;i<=n;++i)
{
b[i]=a[1]-a[i];
if(b[i]>0) f2=max(f2,b[i]);
else f1=max(f1,-b[i]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=0;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
if(f2>=f1)
{
printf("%d\n%d %d\n",ans,X0,D);
return 0;
}
int sz=sqrt(n),last=0;
for(int i=1;last<=n;i+=sz)
{
f1=f2=0;
for(int j=2;j<=n;++j)
{
b[j]+=(i==1?1:sz)*(j-1);
if(b[j]>0) f2=max(f2,b[j]);
else f1=max(f1,-b[j]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=i;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
if(f2>=f1)
{
for(int j=2;j<=n;++j)
b[j]-=(i==1?1:sz)*(j-1);
for(int j=last+1;j<=i;++j)
{
f1=f2=0;
for(int k=2;k<=n;++k)
{
b[k]+=(k-1);
if(b[k]>0) f2=max(f2,b[k]);
else f1=max(f1,-b[k]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=j;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
if(f2>=f1)
{
printf("%d\n%d %d\n",ans,X0,D);
return 0;
}
}
}
last=i;
}
return 0;
}
【二分答案】【中位数】codeforces 394 bun的更多相关文章
- 【二分答案】Codeforces Round #402 (Div. 2) D. String Game
二分要删除几个,然后暴力判定. #include<cstdio> #include<cstring> using namespace std; int a[200010],n, ...
- Codeforces 700A As Fast As Possible(二分答案)
[题目链接] http://codeforces.com/problemset/problem/700/A [题目大意] 有一辆限载k人速度为v2的车,n个步行速度均为v1的人要通过一段长度为l的距离 ...
- Codeforces Round #276 (Div. 1) E. Sign on Fence (二分答案 主席树 区间合并)
链接:http://codeforces.com/contest/484/problem/E 题意: 给你n个数的,每个数代表高度: 再给出m个询问,每次询问[l,r]区间内连续w个数的最大的最小值: ...
- Codeforces Round #425 (Div. 2) Problem C Strange Radiation (Codeforces 832C) - 二分答案 - 数论
n people are standing on a coordinate axis in points with positive integer coordinates strictly less ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划
There are n people and k keys on a straight line. Every person wants to get to the office which is l ...
- Codeforces 772A Voltage Keepsake - 二分答案
You have n devices that you want to use simultaneously. The i-th device uses ai units of power per s ...
- Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1) C. Save the Nature【枚举二分答案】
https://codeforces.com/contest/1241/problem/C You are an environmental activist at heart but the rea ...
- [Codeforces 1199C]MP3(离散化+二分答案)
[Codeforces 1199C]MP3(离散化+二分答案) 题面 给出一个长度为n的序列\(a_i\)和常数I,定义一次操作[l,r]可以把序列中<l的数全部变成l,>r的数全部变成r ...
- [Codeforces 865C]Gotta Go Fast(期望dp+二分答案)
[Codeforces 865C]Gotta Go Fast(期望dp+二分答案) 题面 一个游戏一共有n个关卡,对于第i关,用a[i]时间通过的概率为p[i],用b[i]通过的时间为1-p[i],每 ...
随机推荐
- [poj 2104]主席树+静态区间第k大
题目链接:http://poj.org/problem?id=2104 主席树入门题目,主席树其实就是可持久化权值线段树,rt[i]维护了前i个数中第i大(小)的数出现次数的信息,通过查询两棵树的差即 ...
- C# new override
A -> virtual Fun B : A -> override Fun C : B -> override Fun D : C -> new virtual Fun E ...
- html中音频和视频
HTML5音频中的新元素标签 src:音频文件路径. autobuffer:设置是否在页面加载时自动缓冲音频. autoplay:设置音频是否自动播放. loop:设置音频是否要循环播放. contr ...
- jquery学习之add()
解读: add() 将元素添加到匹配元素的集合中 例1: <!DOCTYPE html> <html> <head> <style> div { wid ...
- 在eclipse中使用JUnit4,以及使用JUnit4进行单元测试的技巧
一 在eclipse中使用JUnit4 首先在工程上右键,选择属性,找到Java Builder Path,添加JUnit4的lib,如下图: 在要测试的类上右键新建 Junit test cas ...
- Spring securiuty 过滤器
1. HttpSessionContextIntegrationFilter 位于过滤器顶端,第一个起作用的过滤器. 用途一,在执行其他过滤器之前,率先判断用户的session中是否已经存在一个Sec ...
- SSL步骤
SSL步骤 被认证的服务器 1.创建keystore 2.创建信任证书 3.导出信任证书供客户端使用 客户端 1.创建keystore(如果不存在) 2.导入信任证书
- Linux实现利用SSH远程登录服务器详解
Linux实现利用SSH远程登录服务器详解 http://www.111cn.net/sys/linux/55152.htm
- linux下源码安装netcat
linux下源码安装netcat http://blog.chinaunix.net/uid-20783755-id-4211230.html 1,下载netcat源码,netcat-0.7.1-13 ...
- selenium与360极速浏览器driver配置
1)下载浏览器对应的driver,浏览器版本与driver对应关系,网址:http://www.cnblogs.com/JHblogs/p/7699951.html:driver下载地址:http:/ ...