- “二分”不用二分,神奇
- 分析:
- '.'时,猜的数正确,数字的范围[a,a];
- '-'时,猜的数太小,数字范围[a+1,+∞);
- '+'时,猜的数太大,(-∞,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;
}