您的位置:首页 > 其它

二分搜索及其思想(挑战例题总结)

2015-12-26 23:09 267 查看
二分搜索的思想中,对临界值的区分比较模糊。。。

首先看了挑战的第一章,额,发现 lb,ub的区分看不懂啊。。。为毛是初始化是-1和n啊???

纠结很久......

然后又看看low_bound和upper_bound函数的源代码。。。。

lower_bound()

upper_bound()

我感觉书上是那个lb不需要是-1啊(不想纠结了ORZ)

iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。

iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值> key的第一个元素。

upper_bound()-lower_bound()就是相同的个数了2333

low_bound()与upper_bound()区别就是<与<=号的区别。。这个自己手码一次就可以了。。。

贴上自己喜欢的代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int num[10];

int Low_bound(int *Array,int Size,int key)
{
int pos;
int first,last,middle;
first=0;
last=Size;
pos=first;
while(first<last)
{
int middle=(first+last)>>1;
if(Array[middle]<key)
{
first=middle+1;
pos=first;
}
else
{
last=middle;
pos=last;
}
}
return pos;
}

int main()
{
for(int i=0;i<5;i++) scanf("%d",&num[i]);
cout<<Low_bound(num,5,2)<<endl;
return 0;
}


然后再是二分的思想解决一些问题。。。。。。。。

因为二分查找的效率狠高,所以可以根据二分查找到答案范围。。。

一般跟贪心和数学相关的一些转化。。。。(题目还是做得太少了。等等后来做多了再反思一下)

然后书上的3个例子自己手码一次。再做题目.....

1.假定一个解判断是否可行

2.最大化最小值

3.最大化平均值

1. POJ 1064 Cable master

需要正确的精度姿势。。。。。

1.double最好用cin

2.floor是向下取整函数。。。

精度

代码:

#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include<sstream>
#include <cmath>
using namespace std;
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define INF 1001000
#define sq(x) (x)*(x)
#define eps (1e-10)
#define clr(x) memset((x),0,sizeof (x))
#define cp(a,b) memcpy((a),(b),sizeof (b))

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int maxn=10100;

double str[maxn];
int N,K;

bool c(double len)
{
int sum=0;
for(int i=0;i<N;i++)
sum+=(int)(str[i]/len);
return  sum>=K;
}

int main()
{

cin>>N>>K;
for(int i=0;i<N;i++) cin>>str[i];
double left,right,mid;
left=0,right=INF;
for(int i=0;i<100;i++)
{
mid=(left+right)/2;
if(c(mid)) left=mid;
else       right=mid;
}
printf("%.2f\n",floor(right*100)/100);
return 0;
}


2.最大化最小值

POJ 2456 Aggressive cows

自己代码

#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include<sstream>
#include <cmath>
using namespace std;
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define INF 1e9+10
#define sq(x) (x)*(x)
#define eps (1e-10)
#define clr(x) memset((x),0,sizeof (x))
#define cp(a,b) memcpy((a),(b),sizeof (b))

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int maxn=101000;
int cow[maxn];
int N,C;

bool c(int x)
{
int num=1;
int last=0;
for(int k=1;k<N;k++)
{
if(cow[k]-cow[last]>=x)
{
last=k;
num++;
}
}
return num>=C;
}

int main()
{
cin>>N>>C;
for(int i=0;i<N;i++) cin>>cow[i];
sort(cow,cow+N);
int left,right,mid;
left=0;
right=INF;
for(int i=0;i<100;i++)
{
mid=(left+right)>>1;
if(c(mid)) left=mid;
else       right=mid;
}
cout<<left<<endl;
return 0;
}


书上代码:

#include <iostream>
#include <map>
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include<sstream>
#include <cmath>
using namespace std;
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define INF 1e9+100;
#define sq(x) (x)*(x)
#define eps (1e-10)
#define clr(x) memset((x),0,sizeof (x))
#define cp(a,b) memcpy((a),(b),sizeof (b))
const int maxn=100100;

int pos[maxn];
int N,C;

bool c(int d)
{
int last,cnt;
last=0;
cnt=1;
for(int i=1;i<C;i++)
{
while(cnt<N&&pos[cnt]-pos[last]<d)
cnt++;
if(cnt==N) return false;
last=cnt++;
}
return true;
}

int main()
{
scanf("%d%d",&N,&C);
for(int i=0;i<N;i++) scanf("%d",&pos[i]);
sort(pos,pos+N);
int lb,ub;
lb=0;
ub=INF;
while(ub-lb>1)
{
int mid=(lb+ub)/2;
if(c(mid)) lb=mid;
else       ub=mid;
}
printf("%d\n",lb);
return 0;
}


自己的代码比书上慢了很多,原因是二分的结束条件判断不好。。。。

mark一个...

然后想想 输出是left还是right。。。不要凭印象随便写。。。。看代码,满足是左,不满足是右。。。。所以输出为左,想想就清楚了。。。

最大化平均值

需要一个数学思维转换下。。即可。

恩!OK。开始做题目了、
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: