1. 程式人生 > >【演算法競賽進階指南】CH1301鄰值查詢(set)

【演算法競賽進階指南】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; }