• “二分”不用二分,神奇
  • 分析:
  1. '.'时,猜的数正确,数字的范围[a,a];
  2. '-'时,猜的数太小,数字范围[a+1,+∞);
  3. '+'时,猜的数太大,(-∞,a-1];

思路:1.暴力:假设其中一条正确,往下遍历看下面是否正确,一直保留最大的可能正确数,一般都会超时;

2.根据范围找出某个位置为最多的正确回复次数,利用Map记录猜的数给出的范围临界点的正确回复的变化量;

3.利用x(假设为正确的数)从-INT_MAX(假设为负无穷)一直往INT_MAX(假设为正无穷)走;

4.根据x从小到大遍历,若裁判回复正确,则证明x进入范围内,根据猜的数知道数字范围,X进入范围内则左位置++代表此范围为正确回复,当x离开范围则右临界点往后一位--判定此为错误回复,注意从小到大看;

5.遍历MAP,利用h动态记录正确回复的数量,ans保留最大值。

代码如下:

#include <iostream>
#include<string>
#include<algorithm>
#include<map>
#include<limits.h>
#include<map>
using namespace std;
char ch[100005];
int a[100005];
int inM = INT_MAX;
map<int, int>m;
int  main()
{
	int n, h = 0, ans = -1;
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> a[i] >> ch[i];
	for (int i = 1; i <= n; i++)
	{
		if (ch[i] == '.')m[a[i]]++, m[a[i] + 1]--;
		else if (ch[i] == '+')m[-inM]++, m[a[i]]--;
		else if (ch[i] == '-')m[a[i] + 1]++;
	}
	for (auto p = m.begin(); p != m.end(); p++)
	{
		h += p->second;
		ans = max(ans, h);
	}
	cout << ans;
}