二分法
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); }
以上是关于二分法的主要内容,如果未能解决你的问题,请参考以下文章