2020年4月23日
1、基本算法——查找
查找类问题也是十分基本的问题。排序类问题通过上一篇博文,可以较为方便的解决。查找类问题,我们最主要需要关心的就是二分查找。
基本思想我们这里就不概括了。(注意数组有序)
二分查找代码:
int top=n-1,base=0;
int tmp_num=0; //待查询的学号
while(top>=base){ //注意大于等于
int mid=(top+base)/2; // 注意这里
if(buf[mid].num==tmp_num) {//二分查找找到了
ans=mid;
break;
}
else if(tmp_num<buf[mid].num){ //查找点小于中间点,需要查找左边的区间(从小到大)
top=mid-1;
}
else base=mid+1;
}
二分查找还有一个较为经典的应用,就是在一个有序数组中的定界。(给定一个数字,确定这个数字在该数组中的位置(这个位置使得该位置的数与该位置左边的数都小于它,右边的数都大于它))
代码:
int top=n-1,base=0,target=50; //为50定界
while(top>=base){
middle
if()
}
2、基本算法——贪心
思想: 总是选择当前情况下的最优解。
难点:选择一个合适的贪心策略。
举例1:看电视(《王道考研机试》)
看电视问题:
需要我们思考的是,我们在这道题目当中是否可以运用贪心思想,如果运用的话,运用哪一种贪心策略。
重点:当前选择一个节目,选择一个结束时间最早的。
每次选择的时候,同样看了一个节目,选择结束时间最早的,保证看了节目的同时,尽可能的为下一个节目的观看腾出时间(多看几个节目)。
代码
#include <stdio.h>
#include<algorithm>
using namespace std;
//最主要的问题:贪心的策略是什么。
struct program{//电视节目结构体
int startTime;//节目开始时间
int endTime;//节目结束时间
bool operator < (const program &A)const{//重载小于号,保证sort函数能够按照结束时间升序排列
return endTime<A.endTime;
}
}buf[100];
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
if(n==0)
break;
for(int i=0;i<n;i++){
scanf("%d%d",&buf[i].startTime,&buf[i].endTime);
}//输入
sort(buf,buf+n);//按照结束时间升序排列
int currentTime=0,ans=0;
for(int i=0;i<n;i++){
if(currentTime<=buf[i].startTime){
currentTime=buf[i].endTime;
ans++;
}
}
printf("%d",ans);
}
}
举例2:买股票:(力扣-122)
贪心算法的实现:因为规定只能持有一只股票,贪心的策略:我们已知明天的股票是跌还是涨(事实上我们通过输入计算机的数组知道的。)如果明天的股票比今天的贵,我们在今天买股票,并在明天卖掉,如果明天的股票比今天的便宜,我们就不买今天的股票。这样我们便可以保证我们始终是赚钱的。这也就是最优解。
代码
#include <stdio.h>
int buf[30000]; //输入规模
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
int tmp=buf[i];
scanf("%d",&tmp);
buf[i]=tmp;
}//