【算法竞赛进阶指南】CH1301邻值查找(set)

给定一个长度为 n 的序列 A,A 中的数各不相同。对于 A 中的每一个数 \(A_{i}\),求:\(min(1\leq j<i)\left | A_{i}-A_{j} \right |\)
以及令上式取到最小值的 j(记为 \(P_{i}\))。若最小值点不唯一,则选择使 \(A_{j}\) 较小的那个。

通过定义结构体和重载运算符,将set维护成一个有序的集合,
每次插入前,去找到当前这个数字最接近的值的前驱和后驱,比较前驱和后驱,找到最小的j,
如果找不到大于等于这个数字,能么需要判断end()(注意stl中全部都是以左闭右开的形式来保存的),去直接输出end()-1,同理如果是begin(),直接输出begin()+1


#include<iostream>
#include<cstdio>
#include<set>
using namespace std;

struct node{
    int num,id;
    bool operator<(node a) const{
        return num<a.num;
    }
};
set<node>s;

int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int tmp;
        scanf("%d",&tmp);
        if(i==1) {s.insert(node{tmp,i});continue;}
        set<node>::iterator right=s.lower_bound(node{tmp,0}),left=right;left--;
        if(right==s.end()){
            printf("%d %d\n",tmp-left->num,left->id);
        }else if(right==s.begin()){
            printf("%d %d\n",right->num-tmp,right->id);
        }else if((tmp-left->num)<=(right->num-tmp)){
            printf("%d %d\n",tmp-left->num,left->id);
        }else{
            printf("%d %d\n",right->num-tmp,right->id);
        }
        s.insert(node{tmp,i});
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/rign/p/10097432.html