二分法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分法相关的知识,希望对你有一定的参考价值。

今天做了两个二分的题目,感觉真的很神奇,现在把代码贴一下,方便以后查阅。

codeforces 779D

题目是给你一个操作串,然后给你一个待匹配串,接下来给你n个数字(n是操作串的长度),然后依次删除ai对应的操作串的下标,问你到第几个的时候,

操作串中没有待匹配串。

 

思路就是二分查找,查找什么呢?查找将前x个str[ai]删除,看是否满足条件,然后恢复,继续向左或者向右查找

 

简单看了一下二分,关键部分有几个,处理mid的时候,有2种方式,第一种是处理整形时候的方式,第二种是处理浮点型数据的方式。

具体看代码。

 

#include <iostream>
#include <string>
using namespace std;
string aim,str;
const int Maxn = 230010;
int del[Maxn];
bool vis[Maxn];

bool ok( int l,int r ){
	bool flag = false;
	for( int i = 0; i <= r; i++ ){//这里要把mid前面全部清空
		vis[del[i]] = true;
	}
	int j = 0;
	for( int i = 0; i < str.length(); i++ ){
		if( !vis[i] and str[i] == aim[j] ){
			j++;
		}
	}
	if( j == aim.length() ){
		flag = true;
	}
	for( int i = 0; i <= r; i++ ){
		if( vis[del[i]] ){
			vis[del[i]] = false;
		}
	}
	return flag;
}

int main(){
	cin >> str >> aim;
	int len = str.length();
	for( int i = 0; i < len; i++ ){
		scanf("%d",del+i);
		del[i] -= 1;
	}
	int l = 0,r = len-1;
	int mid;
	while( l <= r ){
		mid = (l+r)/2;
		if( ok( l,mid ) ){
			l = mid+1;//重点
		}else{
			r = mid-1;
		}
	}
	cout << l << endl;
}

 

 

第二题是codeforces 782B

题意是,有一条跑道,跑道上有N个人,每个人的位置是ai,然后给你每个人的速度vi,让你在跑道上找个点,让每个人都要到达那里所需要的最小时间是多少

 

 

思路:两种方法写,社会我韩神说用二分查找的方式,我怎么也想不出,后来他告诉我这个so easy,只要二分时间就可以了,给个时间的话,每个人就会又个活动范围,只要保证某给点在左右的人的活动范围以内就可以了。再次%%%%%%%%%%%%%%%%%%%%%%%%%%社会我韩神

 

#include <iostream>
#include <algorithm>
using namespace std;

const int Maxn = 60100;
int N;

struct Node{
	double a,b;
}node[Maxn];

bool ok( double t ){
	double l = -1e9-7,r = 1e9+7;
	double x,y;
	for( int i = 0; i < N; i++ ){
		x = node[i].a-node[i].b*t;
		if( x < 0 ){
			x = 0;
		}
		y = node[i].a+node[i].b*t;
		if( y < l || x > r ){
			return false;
		}
		if( x >= l ){
			l = x;
		}
		if( y <= r ){
			r = y;
		}
	}
	return true;
}


int main(){
	cin >> N;
	for( int i = 0; i < N; i++ ){
		cin >> node[i].a;
	}
	for( int i = 0; i < N; i++ ){
		cin >> node[i].b;
	}
	double l = 0,r = 1e9+7;
	double mid;
	while( r-l >(1e-7) ){//这里是处理浮点数的二分的方法
		mid = (l+r)/2;
		if( ok(mid) ){
			r = mid;//这里和整形不一样,需要注意
		}else{
			l = mid;
		}
	}
	printf("%.6lf",r);
}

 

以上是关于二分法的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数