题解 | #万万没想到之抓捕孔连顺#

万万没想到之抓捕孔连顺

http://www.nowcoder.com/practice/c0803540c94848baac03096745b55b9b

题目的要求是相距最远的2个人距离不超过d,所以当我们确定了距离最远的2个人的距离,那么第3个人的坐标就是在这2人之间进行排列组合。所以问题就转化为给定一有序数组a,对于a中的每一个元素查找出距离最大且小于d的另一个元素

普通直接遍历会超时因为数组有序,可以用二分查找或者滑动窗口(记得开long long):

1.二分查找:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int v[1000005];
//二分查找
ll b_s(ll l,ll r,ll target){
    ll res = r;
    while(l <= r){
        ll mid = (l+r)/2;
        if(v[mid] >= target){     //check条件是判断是否满足,满足就暂时记下来
            res = mid;
            r = mid-1;
        }else{
            l = mid+1;
        }
    }
    return res;
}

const ll mod = 99997867;
!
int main(){
    ll n,d;  cin >> n >> d;
    for(ll i=0;i<n;i++){
        cin >> v[i];
    }
    ll ans = 0;
    for(ll i=0;i<n;i++){
        ll a = v[i];
        ll j;
        if(v[n-1] <= a+d){
            j = n-1;
        }else{
            j=b_s(i,n-1,a+d);
            if(v[j] > a+d){
                j--;
            }
        }
        ll x = j-1-i;
        ans += (x*(x+1)/2)%mod;
        ans = ans%mod;
    }
    cout << ans;
    return 0;
}

滑动窗口,指针不回溯:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

//滑动窗口
const ll mod = 99997867;
int main(){
    ll n,d;  cin >> n >> d;
    ll v[n];
    for(ll i=0;i<n;i++){
        cin >> v[i];
    }
    ll ans = 0,j=0;
    for(ll i=0;i<n;i++){
        while(v[j] - v[i] <= d && j <= n-1){
            j++;
        }
        ll x = j-1-i-1;
        ans += x*(x+1)/2;
        ans = ans%mod;
    }
    cout << ans;
    return 0;
}

全部评论

相关推荐

点赞 评论 收藏
分享
无敌虾孝子:喜欢爸爸还是喜欢妈妈
点赞 评论 收藏
分享
11-09 14:54
已编辑
华南农业大学 产品经理
大拿老师:这个简历,连手机号码和照片都没打码,那为什么关键要素求职职位就不写呢? 从上往下看,都没看出自己到底是产品经理的简历,还是电子硬件的简历? 这是一个大问题,当然,更大的问题是实习经历的描述是不对的 不要只是去写实习流程,陈平,怎么去开会?怎么去讨论? 面试问的是你的产品功能点,是怎么设计的?也就是要写项目的亮点,有什么功能?这个功能有什么难处?怎么去解决的? 实习流程大家都一样,没什么优势,也没有提问点,没有提问,你就不得分 另外,你要明确你投的是什么职位,如果投的是产品职位,你的项目经历写的全都是跟产品无关的,那你的简历就没用 你的面试官必然是一个资深的产品经理,他不会去问那些计算机类的编程项目 所以这种四不像的简历,在校招是大忌
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务