牛客 - 二分

1、题目表述

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题号:NC207053
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

我们刚刚学了二分查找——所谓二分查找就是在一堆有序数里找某个符合要求的数。在学完二分查找之后如果让你玩猜数游戏(裁判选定一个目标数字,你说一个数裁判告诉你是高了还是低了直到你猜到那个数)的话,显然你会用二分的方式去猜。

但是不是每一个玩猜数游戏的人都知道二分是最好,甚至一个健忘的玩家都有可能在得到裁判回答的下一个瞬间就忘了他之前问了什么以及裁判的回答),而现在更可怕的是,这个告诉你猜的数是高还是低的裁判他也很健忘,他总是薛定谔的记得这个目标数字,也就是说他的回答有可能出错。我们已经不关心这个不靠谱的游戏本身了,我们更关心裁判这个薛定谔的记得到底有几个是记得......

现在给出这个健忘的玩家的所有猜测和裁判的所有回答,问裁判最多能有多少次是记得目标数字的,即裁判的回复是符合情况的。

输入描述:

第一行包含一个正整数n,表示裁判的回答数(也是玩家的猜数次数)。

接下来n行,首先是猜的数,然后是一个空格,然后是一个符号。符号如果是“+”说明猜的数比答案大,“-”说明比答案小,“.”说明猜到了答案。

输出描述:
包含一个正整数,为裁判最多有多少个回答是正确的。

示例1

输入
4
5 .
8 +
5 .
8 -
输出
3
说明
当目标数组是5时,5 . 5 .  8 + 这三个回答都是正确的
备注:

n≤100000
所有数的大小都小于int类型最大值。

2、思路

        该题让我们根据裁判的回答和与正确数值的关系(实际上就是给出可能正确的数值的范围)来计算出裁判最多有多少回答是正确的。若为 "x . ",正确区间就是 [x]; 若为"x -",正确区间就是

[x+1,∞);若为"x +",正确区间就是(-∞,x-1]。

        由于题干有提示“所有数的大小都小于int类型最大值”,int最大数值小于 1e11,所以本题中1e11可以等效为 ∞。

        假设区域在[n, m],那么就让[n]++,[m+1]--。用 n 位置的数值大小来代表所有的n~m这个区域上的正确的次数,这样在(-∞,n)的前缀和就是 0 ,在[n,m]的前缀和就是 1 ,在(m,∞)前缀和复归 0。(差分前缀和)

        在此题上就是
        x . [x]++  [x+1]-- 
        x +  [-∞]++  [x]--
        x -  [x+1]++ [∞]-- 

        然后由于int数值范围太大,所以用map来存取位置,用foreach来遍历map,在map中会自动把int、long long类型的数值按键值升序排列,正好符合前缀和计算需求。

3、代码

#include<bits/stdc++.h>
using namespace std;
map<long long, int> a;
int main()
{
    int i, j;
    int n;
    long long maxer = 1e11;
    cin >> n;
    for (i = 1; i <= n; i++)
    {
        int x;
        char c;
        cin >> x >> c;
        if (c == '.')
        {
            a[x]++;
            a[x + 1]--;
        }
        else if (c == '+')
        {
            a[-maxer]++;
            a[x]--;
        }
        else
        {
            a[x + 1]++;
            a[maxer]--;
        }
    }
    int sum = 0;
    int result = 0;
    for (auto it : a)
    {
        sum += it.second;
        result = max(result, sum);
    }
    cout << result;
    return 0;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值