题目简述:
对于序列A中的任意数 A i A_i Ai, 求 m i n 1 ≤ j < i ∣ A i − A j ∣ min_{1\leq j < i}|A_i - A_j| min1≤j<i∣Ai−Aj∣ ,即求当前标号之前,与 A i A_i Ai最接近的值及其索引。
方法一:
利用值及索引建立 vector, 然后根据值对原数组进行排序。则可得知对于 A i A_i Ai 数值最接近的为 A i − 1 A i + 1 A_{i-1}\ A_{i+1} Ai−1 Ai+1 ,然后根据原数组索引 n 开始倒序循环,这样就可以保证前后两个数一定是索引小于当前索引。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int INF = 2e9 + 7;
struct Node{
int pos, val;
Node *pre, *next;
};
Node *head, *tail, *point;
int n;
Node *pos[N];
vector<pair<int, int>> a;
void insert(Node *&p, pair<int,int> &pa) // pay attention to can not use references
{
// cout << pa.first << " " << pa.second << endl;
Node *nod = new Node;
nod -> val = pa.first;
nod -> pos = pa.second;
nod -> pre = p;
nod -> next = p -> next;
p -> next -> pre = nod;
p -> next = nod;
pos[pa.second] = nod;
}
void Initialization()
{
head = new Node;
tail = new Node;
head -> next = tail;
tail -> pre = head;
head -> val = INF;
for (auto &it : a) {
Node *p = tail -> pre;
insert(tail -> pre, it);
}
tail -> val = -INF;
}
void Del(Node *& p)
{
Node *pre = p -> pre, *next = p -> next;
pre -> next = next;
next -> pre = pre;
delete p;
}
int main()
{
int x; cin >> n;
for (int i = 1; i <= n; i ++) {
cin >> x;
a.push_back(make_pair(x, i));
}
sort(a.begin(), a.end());
Initialization();
/* Node *lis = head;
while (lis != tail) {
cout << lis -> val << " ";
lis = lis -> next;
} */
vector<int> ans;
for (int i = n; i > 1; i --) {
int x = pos[i]->pre->val, y = pos[i]->val, z = pos[i]->next->val;
if (y - x <= z - y) ans.push_back(pos[i]->pre->pos);
else ans.push_back(pos[i]->next->pos);
Del(pos[i]);
}
reverse(ans.begin(), ans.end());
for(auto &it : ans) cout << it << " " << a[it - 1].first << endl;
return 0;
}
方法二:
建立set集合, 键值为 p a i r < i n t , i n t > pair<int,\ int> pair<int, int>, 可知 set 内部重载了pair的的排序函数, 第一优先级为pair.first, 次优先级为pair.second 。 首先处理边界, 将ser中加入INF -INF,方便处理, 从索引 2 开始循环,每次从set中查询优先级大于 m a k e p a i r ( x , i ) make_pair(x, i) makepair(x,i)的节点及优先级小于其的节点, 选择最接近的节点并记录答案, 最后将当前节点插入set 中。
#include <bits/stdc++.h>
using namespace std;
const int INF = 2e9 + 7;
int main()
{
int n, x; cin >> n >> x;
set<pair<int, int>> se;
se.insert({INF, 0});
se.insert({-INF, 0});
se.insert({x, 1});
vector<pair<int, int>> ans;
for (int i = 2; i <= n; i ++) {
cin >> x;
set<pair<int, int>>::iterator itA = se.upper_bound({x, i});
auto itB = itA;
itB --;
if (x - (*itB).first <= (*itA).first - x) ans.push_back({x - (*itB).first, (*itB).second});
else ans.push_back({(*itA).first - x, (*itA).second});
se.insert({x, i});
}
for (auto &it : ans) cout << it.first << " " << it.second << endl;
return 0;
}