原题链接:https://ac.nowcoder.com/acm/problem/207053
题目描述
我们刚刚学了二分查找——所谓二分查找就是在一堆有序数里找某个符合要求的数。在学完二分查找之后如果让你玩猜数游戏(裁判选定一个目标数字,你说一个数裁判告诉你是高了还是低了直到你猜到那个数)的话,显然你会用二分的方式去猜。
但是不是每一个玩猜数游戏的人都知道二分是最好,甚至一个健忘的玩家都有可能在得到裁判回答的下一个瞬间就忘了他之前问了什么以及裁判的回答),而现在更可怕的是,这个告诉你猜的数是高还是低的裁判他也很健忘,他总是薛定谔的记得这个目标数字,也就是说他的回答有可能出错。我们已经不关心这个不靠谱的游戏本身了,我们更关心裁判这个薛定谔的记得到底有几个是记得......
现在给出这个健忘的玩家的所有猜测和裁判的所有回答,问裁判最多能有多少次是记得目标数字的,即裁判的回复是符合情况的。
输入描述
第一行包含一个正整数n,表示裁判的回答数(也是玩家的猜数次数)。
接下来n行,首先是猜的数,然后是一个空格,然后是一个符号。符号如果是“+”说明猜的数比答案大,“-”说明比答案小,“.”说明猜到了答案。
输出描述
包含一个正整数,为裁判最多有多少个回答是正确的
样例1:
输入
4
5 .
8 +
5 .
8 -
输出
3
说明:当目标数组是5时,5 . 5 . 8 + 这三个回答都是正确的
首先,说一下差分性质:给区间[l, r]中的每个数加上c:B[l] += c, B[r + 1] -= c
我们可以利用Map将数据离散化存储(int范围比较大),然后具体讨论三种情况:
1.遇到5 . 则区间[5,5]加上1
2.遇到8+ 则遇到小于8的数时8+都可以算一种答案,即区间(-∞,7]加上1
3.遇到8- 则遇到大于8的数时8-可以算一种答案,区间[9,+∞)加上1
接着遍历一遍map取出最大值
具体解释:,相当于我们把区间都画出来,看看那个点被区间覆盖的最多。map的左端点右端点会从小到大排好序,到某个区间左端点时回答正确数量+1,出了某个区间的有端点时回答正确数量-1。
在图中可以发现点5符合题意,答案为3
实际在map操作中则是
1.遇到第一个map[-∞]=1,now = 1;
2.遇到map[5] = 2,now = 3;
3.map[6] = -2,now = 1;
4.接着map[8] = -1,now = 0;(此时目标猜为8)
5.map[9] = 1,now = 1;
6.map[+∞] = -1,now = 0;
#define int long long
const int N = 100000+5;
map<int,int>mp;
#define MAX 1e16
void solve()
{
int n;
cin>>n;
for(int i=0;i<n;i++){
int e;
char ch;
cin>>e>>ch;
if(ch=='.'){
mp[e]++;
mp[e+1]--;
}else if(ch=='+'){
mp[-MAX]++;
mp[e]--;
}else if(ch=='-'){
mp[MAX]--;
mp[e+1]++;
}
}
int ans = 0;
int now = 0;
for(auto it:mp){
now += it.second;
ans = max(ans,now);
}
cout<<ans;
}