二分3——2021-02-03第二更

二分3——二分答案

T1 母鸡下蛋(解法2)

题目:

题目二分2那里有,就不敲出来了,
要看题目的话……这里→ 二分2——2021-02-02更

思路:

解法1中我们用的是二分查找,这次用二分答案来做,每次都求一个x,再写一个函数用来判断x个鸡窝能否装完这些蛋,如果可以,则说明目前x个鸡窝满足条件,那就往小设置x,如果不可以,则将x往大设置。最后输出最小的x。

代码:

#include<bits/stdc++.h>
using namespace std;
long long n,a[1000010],h,t;

bool chk(int x)
{
    
    
	for(int i=x;i<=n;i++)
		if(a[i]-a[i-x]>=t)
			return true;
	return false;		
}
int main()
{
    
    
	ios::sync_with_stdio(false);
	cin>>n>>t;
	for(int i=1;i<=n;i++)
	{
    
    
		int k;
		cin>>k;
		a[i]=a[i-1]+k;
	}
	int z=1,y=n;
	while(z<y)
	{
    
    
		int m=(z+y)/2;
		if(chk(m))
			y=m;
		else
			z=m+1;	
	}	
	if(chk(y))
		cout<<y;
	else
		cout<<"Angry";	
	return 0;
} 

T2 排队上车

题目:

现在有 n 个旅游团在排队等候观光车,每个旅游团有 ai 人,目前有 k 部巴士,各旅游团要安排在同一部车上,并且要按排队顺序依次上车。

请问如何分组,使得大巴中最多的人数最小?

例如:1 2 3 4 5 6 分为3组,可以分为 {1 2 3} {4 5} {6},最大值为9;也可以分为{1 2 3 4} {5} {6},最大值为10。因此第一种方案更优。并且第一种方案的最大值是所有方案中最小的。

输入
第1行:2个数 n, k,中间用空格分隔,n为旅游团的数量,k为巴士的数量。(2 <= k < n <= 50000)
第2行包含 n 个空格隔开的整数,表示每个旅游团的人数ai,(1 <= ai <= 10^9)

输出
一个整数,表示最小的最大值。

输入样例
6 3
1 2 3 4 5 6

输出样例
9

思路:

这道题目我一开始的时候是想着用for套for来做的,但看了一下数据,完全不可能,50000³,大概是五万亿左右,这么大数据的查找,我就想到要用二分来做,我们还是列举一个最大值x,然后每次用一个布尔型的函数来判断,如果符合条件,那么就往小的数接着做二分,如果不符合,就往大的数做二分。

代码:

#include<bits/stdc++.h>
using namespace std;
long long n,a[1000010],h,t,y,z=0;

bool chk(long long x)
{
    
    
	long long s=0,k=1;
	for(int i=1;i<=n;i++)
	{
    
    
		s+=a[i];
		if(s>x)
		{
    
    
			k++;
			s=a[i];
		}
	}
	if(k<=t)
		return true;
	return false;	
}
int main()
{
    
    
	ios::sync_with_stdio(false);
	cin>>n>>t;
	for(int i=1;i<=n;i++)
	{
    
    
		cin>>a[i];
		y+=a[i];
		z=max(z,a[i]);
	}
	while(z<y)
	{
    
    
		long long m=(z+y)/2;
		if(chk(m))
			y=m;
		else
			z=m+1;	
	}
	cout<<z;
	return 0;
} 

T3 篮球赛

题目:

A班有 n 名学生,在上体育课的时候按学号站成了一排,现在老师要分组进行篮球赛,分组的要求为:不能超过 k 组,每组的同学是按学号连续的。

由于同一组内身高差太大的话容易引起内部矛盾,因此老师定义了一个不和谐度:各组的最高身高与最矮的身高的差值。很显然,这个不和谐度是越小越好,现在给出这 n 个学生的身高,请计算最小的不和谐度。

输入
第一行包括两个正整数 n,k。(1<=k<=n<=10^5)
第二行包括用空格隔开的 n 个正整数,第 i 个正整数 ai 表示学号为 i 的学生的身高。( 1<=ai<=10^9)

输出
包括一个整数,表示最小的不和谐度。

输入样例
8 3
5 7 2 3 8 5 9 4

输出样例
5

思路:

这道题的思路和T2类似,只不过一些细节要注意,其他的就没什么区别。
PS:在判断一段的不和谐度时,是要每循环一次就把最大值和最小值更新一次,而不是只求出一个最高(最低)身高和每个人来比较。

代码:

#include<bits/stdc++.h>
using namespace std;
long long n,a[1000010],h,t,y,w;

bool chk(long long x)
{
    
    
	long long s1=a[1],s2=a[1],k=1;
	for(int i=2;i<=n;i++)
	{
    
    
		s1=max(a[i],s1);
		s2=min(a[i],s2);
		if(s1-s2>x)
		{
    
    
			k++;
			s1=a[i];
			s2=a[i];
		}
	}	
	if(k<=t)
		return true;
	return false;	
}
int main()
{
    
    
	ios::sync_with_stdio(false);
	cin>>n>>t;
	for(int i=1;i<=n;i++)
	{
    
    
		cin>>a[i];
		y=max(y,a[i]);
		w=min(w,a[i]);
	}
	if(n<=t)
	{
    
    
		cout<<0;
		exit(1);
	}
	long long z=1;
	y-=w;
	while(z<y)
	{
    
    
		long long m=(z+y)/2;
		if(chk(m))
			y=m;
		else
			z=m+1;	
	}
	cout<<y;
	return 0;
} 

今日心得:二分答案,就是用二分查找每次列举出一个值,然后判断是否符合要求,再做二分查找,一直做到结束为止。

二分系列——二分1

二分系列——二分2

猜你喜欢

转载自blog.csdn.net/SSL_wyd/article/details/113620735