##震惊!一美国教授看见中国的编程题后,竟说出……
这个是题目http://172.17.11.251/problem/2102247
一个"经典的二分问题",这时候就有可能会有什么萌新问“啊,好难啊,我不会啊,这就是大佬的世界吗,i了i了”在学习这道题之前,我们必须先知道什么是二分
在这里我需要先引出一道题
好吧,这是一道水题,你一定会说“就这,不就一个for循环的事?”
确实,那么这道题呢
你想“就这,一个双重循环的事”
但是结果是现实的
没错,超时了,双重循环超时了
这时候,就要引出今天的主角,二分了!
二分,顾名思义,就是讲数组一分为二,看答案与中间值的比较
看懂了这个,答案就很简单了
#include<bits/stdc++.h> using namespace std; int n,a[100010],s; int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } cin>>s; for(int i=1;i<=n;i++) { int l=i+1,r=n; while(r-l>1) { int mid=(l+r)/2; if(s-a[i]>a[mid]) l=mid; else r=mid; } if(a[l]==s-a[i]||a[r]==s-a[i]) { cout<<"Yes"; return 0; } } cout<<"No"; return 0; }
so easy!
二分的优点在于其永远不会超时(如果你超时了就是你的代码出BUG了)
原因自己品一下
现在你们已经接触基本的二分问题了,但是先别急着做复制书稿,我们先看一下简单一点的题
这里有两道水题,可以自己先练练级
http://172.17.11.251/problem/1061106
http://172.17.11.251/problem/1061105
属实水题嗷,不会做的可以关闭文章了
准备好了吗,下一道题就没有这么水了
不知道你们有没有一种刚出新手村就打Boss的感觉,因为这个程序需要求的是最小的最大那么我们就需要求个值,要求每个数都要大于等于这个数
那我们要如何达到这种操作呢。答案是
#函数
不知道你们多久没有接触到函数了,反正我是有一段时间了
现在找到竟有一种久别重逢的感觉
现在我们要敲代码了
因为我们要判断位置,所以我们要用到BOOL变量
bool ok(long long x) { memset(a,0,sizeof a); long long y=0,k=0;//赋初值 for(long long i=1;i<=d;++i) { while(y<x)//不大于X { if(++k>n)//每次k都要加一并且不可以大于n { return 0; } y+=h[k]; a[k]=i; } y/=2; } return 1; }
就是这样的
鼓掌鼓掌