标签:
Watson gives Sherlock an array A1,A2...AN.
He asks him to find an integer M between P and Q(both inclusive), such that, min {|Ai-M|, 1 ≤ i ≤ N} is maximised. If there are multiple solutions, print the smallest one.
Input Format
The first line contains N. The next line contains space separated N integers, and denote the array A. The third line contains two space separated integers denoting P and Q.
Output Format
In one line, print the required answer.
Constraints
1 ≤ N ≤ 102
1 ≤ Ai ≤ 109
1 ≤ P ≤ Q ≤ 109
Sample Input
3
5 8 14
4 9
Sample Output
4
Explanation
For M = 4,6,7, or 9, the result is 1. Since we have to output the smallest of the multiple solutions, we print 4.
---------------------------------------------------------------------------------------------------------------------------------------------------------------
Solution
二分答案+O(N)构造
复杂度O(N*logQ)
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Implementation
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define pb push_back
int n, p, q;
typedef pair<int,int> P;
vector<P> interv[2];
vector<int> a;
int now, pre;
void merge(P &a, P &b){
int x=max(a.X, b.X);
int y=min(a.Y, b.Y);
if(x<=y) interv[pre].pb({x, y});
}
const int INF=INT_MAX;
bool C(int x){
pre=0, now=1;
interv[pre].clear();
interv[now].clear();
interv[now].pb({p, q});
P l, r;
for(int i=0; i<a.size(); i++){
for(int j=0; j<interv[now].size(); j++){
l={-INF, a[i]-x};
r={x+a[i], INF};
merge(interv[now][j], l);
merge(interv[now][j], r);
}
if(interv[pre].empty()) return false;
interv[now].clear();
swap(pre, now);
}
return true;
}
int bs(int l, int r){ //max
int mid;
while(r-l>1){
mid=(l+r)>>1;
if(C(mid)) l=mid;
else r=mid;
}
return l;
}
int main(){
//freopen("in", "r", stdin);
scanf("%d", &n);
for(int i=0; i<n; i++){
int b;
scanf("%d", &b);
a.push_back(b);
}
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
scanf("%d%d", &p, &q);
C(bs(0, 1e9));
sort(interv[now].begin(), interv[now].end());
printf("%d\n", interv[now][0].X);
}
-------------------------------------------------------------------------------------------------------------------------------
总结
二分答案类问题
提法
求满足条件C(x)的最大/最小的x,其中C(x)是一个关于x的bool表达式。
这类问题能用二分答案解决的条件是C(x)要有单调性,这具体是指
若求使C(x)为真的最大的x,那么C(x)必须满足
若 C(x0)为真,则对任意 x <= x0, C(x)为真
若求使C(x)为真的最小的x,那么C(x)必须满足
若 C(x0)为真,则对任意 x >= x0, C(x)为真
标签:
原文地址:http://www.cnblogs.com/Patt/p/4746329.html