2019第二学年 第五周学习总结

经过了天梯赛的选拔和蓝桥杯的备战和比赛,我发现我自己与竞赛要求还有很大的差距。发现自己离目标相距甚远,并且发现自己的理解速度与深度已经开始跟大佬和老师的进度了。所以我对之后的学习进行了以下的规划与认识:

  1. 认清自己与他人的差距,不要无谓的追求做题进度与数量。
  2. 放缓自己的学习进度,自己安排自己的学习任务,尽量将知识熟练应用。

加油吧,差距也许不会缩小但是我不能停止前进。

上周主要任务:二分搜索及其拓展。

  • 二分搜索:是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
    -例:
    在这里插入图片描述
  • 二分法是一个逐步逼近的搜索算法,使用循环实现对两个端点的比较,每次比较后缩小范围,直至查找到最终的值。

A - River Hopscotch

这是一道看起来不像二分法的问题。在充分理解题目后,发现是一道二分法加上贪心法的题目。在这之后一开始并没有什么思路,在这里参考了一下大佬的思路:
在[min,L]范围内搜索满足下列条件的距离dm:
 1.有且仅有N+2-M个石头(包括起始和终点处的两块石头),他们之间的最小距离为di。(即:任意增减一个石头,他们之间的最小距离就不是di)
 2.dm=max{di};
注意:条件1,2保证dm的唯一性。
那么我们可以二分查找di,以di为间隔依次挑选石头,数量记为cnt,
如果cnt>N+2-M,说明di选小了;
如果cnt<N+2-M,说明di选大了;
如果cnt=N+2-M,不一定满足条件(2),需要继续向上(增大)查找。

自己ac代码:

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
int A[50005];
int T,t,k;
bool C(int x)
{
	int last=0;
	int f=0;
	for(int i=1;i<=t+1;i++)
	{
		if(x>=A[i]-A[f])
			last++;
		else
			f=i;
	}
	if(last>k)
	return 1;
	else
		return 0;
}
int main()
{
	while(cin>>T>>t>>k)
	{
	memset(A,0,sizeof(A));
	A[0]=0;
	for(int i=1;i<=t;i++)
	{
		cin>>A[i];
		//if(i==t)
			//A[i+1]=T;
	}
	A[t+1]=T;//??赋值??
	sort(A+1,A+t+1);
	int lb=0;
	int ub=T;
	while(ub>=lb)
	{
		int mid=(lb+ub)/2;
		if(C(mid))
			ub=mid-1;
		else
			lb=mid+1;
	}
	cout<<lb<<endl;
	}
	//system("pause");
	return 0;
}

Cable master poj 1064

这是书上二分法给出的第二道例题,题目大意是:有n条绳子,他们的长度分别为Li。如果从他们中切割出k条长度相同的绳子的话,这k条绳子最长能有多长?答案保留小数点后两位。

这个问题可以说是一个二分法的简单应用题,只需要套出公式就可以求解。
令:条件C(x)==可以得到k条长度为x的绳子。
初始区间为:min=0,max=INF。
开始对所有绳子进行遍历。

自己ac代码:

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
double L[10005];
int N,K;
bool C(double x)
{
 int num=0;
 for(int i=0;i<N;i++)
 {
  num+=(int)(L[i]/x);
 }
 return num>=K;
}
void solve()
{
 double min=0,max=100000;
 for(int i=0;i<100;i++)
 {
  double mid=(min+max)/2;
  if(C(mid))
   min=mid;
  else
   max=mid;
 }
 printf("%.2f\n",floor(max*100)/100);
}
int main()
{
 cin>>N>>K;
 for(int i=0;i<N;i++)
 {
  cin>>L[i];
 }
 solve();
 system("pause");
 return 0;
}

之后的二分法的题在上周并没有完全吃透,所以在下一周我将继续学习二分法的知识与应用。

无论最后自己有没有机会去参加比赛,我也希望自己现在能继续坚持下去,加油。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值