码迷,mamicode.com
首页 > 其他好文 > 详细

HackerRank and MiniMax

时间:2015-08-20 22:10:56      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:

传送门

Sherlock and MiniMax

技术分享Authored by darkshadows on May 07 2014


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)为真

HackerRank and MiniMax

标签:

原文地址:http://www.cnblogs.com/Patt/p/4746329.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!