描述
有n条绳子,长度分别为L[i]。如果从他们中切割出k条长度相同的绳子的话,这k条绳子每条最长能有多长?(答案保留小数点后两位,规定1单位长度的绳子最多可以切割成100份)
输入格式
输入n,k,(1<=n,k<=10000)
然后n行,输入L[i],代表每一条绳子的长度(1<=L[i]<=100000)
输出格式
切出k条长度相等的绳子最大长度是多少,输出保留两位小数
样例输入
4 11
8.02
7.43
4.57
5.39
输出
2.00
题意
n条绳子能切出k条一样的绳子,最长多长
思路
固定总长和段数要最长的相同长度,没错,就是再0到最长绳子之间二分,其实一开始我想的是0到最短的绳子,我想当然的认为既然所有绳子都要切,也就是最短的也得切最终答案会小于最短的,其实不切也行,所以应该是0到最长的绳子二分。二分后将mid值进行判断,每根绳的长度初以这个mid,就是看能切除几根,加起来与k值进行比较,如果大了,证明还能再切长一点,也有可能这个和刚好就等于k,但是我们不能返回,我们要贪心一点,得试试要是距离再开大一点点,是不是还是得到这个数,于是依然left=mid+1,往大的半段搜索。当我们一路搜索到right<mid时,搜索就要结束了,返回一个值。这个值是right还是mid还是left呢?就要看最后我们得到符合要求的距离后的“再开大一点点”是往哪边开了,如果我们往右开,也就是left=mid+1,那么left就变了,我们得返回right,如果我们往左开,我们改动了right,说明得返回left。
这个题最恶心的就是这个精度啊,我在这wa了八次,处理方法就是我们在输入的时候先乘100再存入数组,最后出答案时再除以100.0转成double,记得小数点后保留两位有效数字。
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
int n,k;
double e,a[100010];
int judge(int m)
{
int sum=0;//用于记录绳子数
for(int i=1;i<=n;i++)
{
sum+=a[i]/m;
}
if(sum>=k)//等于时还得再来
return 1;
else
return 0;
}
int main()
{
while(cin>>n>>k)
{
int maxs=0;
for(int i=1;i<=n;i++)
{
scanf("%lf",&e);
a[i]=e*100;//扩大后存入
if(maxs<a[i])//得到最长绳子长度
maxs=a[i];
}
int left=0,mid,right=maxs;
while(left<=right)
{
mid=(left+right)/2;
if(judge(mid))
left=mid+1;
else
right=mid-1;
}
double res=right/100.0;//是100.0
printf("%.2lf\n",res);
}
return 0;
}
描述
农夫有n个牛栏,m头牛,然后要让你把m个牛都放进牛栏里,让两头牛之前的最大的最小距离
输入格式
输入n,m (1<=m<=n<=100000)
下面n行是牛栏的位置xi (0 <= xi <= 1,000,000,000)
输出格式
输出两头牛最大的最小距离
样例输入
5 3
1
2
8
4
9
样例输出
3
题意
求出给定的n个直线排列的牛栏中,每只牛被放入后两牛之间最小距离的最大值是多少。
思路
一开始看到这个最小距离的最大值是一脸懵逼的,根本没有思路,一直在想要对什么二分,此处我们要查找的量是距离,那么应该用可以取到的距离的最大值和最小值进行二分。最大距离就是整个牛栏的长度,也就是第一个牛栏到最后一个牛栏的距离,最小距离懒得算了,就取0吧。第一个牛栏里面肯定是要放牛的,因为牛栏的数目有限,牛又要都放进去,还要求最大的最小距离,如果你还浪费牛栏的话那肯定不行,mid就是每次二分得到的最小距离,然后进入判断,看第一个牛栏跟第二个牛栏之间的间隔与mid谁大,看放不放的下,放不下就要往后走,比较mid和第一个牛栏与第三个牛栏的距离,如果能放下,将牛数减一,下次就要比较第三个和第四个之间的距离了,所以我们要有一个标记记录最新的已经放牛的牛栏。直到把所有的牛放完或已经遍历完所有牛栏,如果牛没放完,则这个mid不行返回flase,如果放完了则要将mid再往大开一点(道理同上提思路)。
AC代码
#include<iostream>
#include<algorithm>
using namespace std;
int a[100010];
int n,c;
int putcow(int mid)
{
int cnt=1,p=a[1];//第一个牛栏一定要放牛
for(int i=2;i<=n;i++)
{
if(a[i]-p>=mid)//两牛栏间距大于最小距离
{
cnt++;
p=a[i];
}
}
if(cnt>=c)
return 1;
else
return 0;
}
int find()
{
int left=0,right=a[n]-a[1],mid;
while(left<=right)
{
mid = (left+right)/2;
if(putcow(mid))
left=mid+1;
else
right=mid-1;
}
return right;
}
int main()
{
while(scanf("%d%d",&n,&c)!=EOF)
{
int i;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);//牛量比较大来一手sort算了,免得时间超限
printf("%d\n",find());
}
}