给定一个长度为 n 的序列 A,A 中的数各不相同。对于 A 中的每一个数 A_i,求:
min(1≤j<i) |A_i-A_j|以及令上式取到最小值的 j(记为 P_i)。若最小值点不唯一,则选择使 A_j 较小的那个
进阶指南的例题,一开始没看懂写法。
题意大概是,给一个数列,对其中每一项,在前面所有项中找到一个数,与它的差的绝对值最小。(因此要求n-1个值,即除了第一项)
大致做法是,以最后一位为对象开始查找,那么此时它前面所有的数都是可以拿来用的,而这个时候用一个链表,来将数列排序之后链接在一起。
此时对链表每一项a_n,a_n-1和a_n+1其中必然有一个是和它的差绝对值最小的那一个项,但是,这两个项可能在原数列中不是在a_n的前面,也就是说,不合法。但如果是原数列中最后一项,那么此时链表中所有值都合法,然后,找出此项结果,把该项在链表中删除,可以删除,就意味着这一项对链表其他项寻找结果不会有影响,因为在原数列中它在所有项后面,必然不能取,因此结论成立,此时再找剩下的在原数列中最后一项,数学归纳法得出。
做出这题,一来是会这种类似于高等代数中的对式子的变型处理,二来是会写这个链表。真的很不好写。。。数据的对应,比较难处理。这题我错在两个地方,一个是读错题意,输出错了数据,而来是将链表的head和tail在排序之前赋值,然后和其他数值一起排序导致出错,这题我对数据的处理显然是很不得当,再接再厉把。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=100010;
int tot,n,head,tail,q;
struct node{
int x,y;
int val,next,pre;
}a[maxn];
void initialize()
{
tot=2;head=1,tail=2;
a[head].next=tail;
a[tail].pre=head;
//cout<<endl<<endl<<a[2].pre<<endl;
}
void insert(int p,int v)
{
q=++tot;
//cout<<tot<<endl;
a[q].val=v;
a[a[p].next].pre=q;
a[q].next=a[p].next;
a[p].next=q;
a[q].pre=p;
}
void move(int p)
{
a[a[p].pre].next=a[p].next;
a[a[p].next].pre=a[p].pre;
}
bool cmp(const node &a,const node &b)
{
return a.x<b.x;
}
int b[maxn],c[maxn];
vector < pair<int,int> >vec;
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].x;
a[i].y=i;
}
sort(a+1,a+1+n,cmp);
initialize();
int t=1;
//cout<<a[2].pre<<endl;
for(int i=1;i<=n;i++){
insert(t,a[i].x);
b[a[i].y]=tot;
c[tot]=a[i].y;
t=tot;
}
/*for(int i=1;i<=n+2;i++){
//printf("pos=%d,a[pos].pre=%d,a[pos].next=%d\n\n",i,a[i].pre,a[i].next);
}*/
for(int i=n;i>1;i--){
int pos=b[i];//i=3,pos=4;
//cout<<i<<" "<<pos<<endl;
int px=a[pos].pre,nx=a[pos].next;
//cout<<px<<" "<<nx<<endl;
//printf("pos=%d\n\n",pos);
//printf("px=%d,nx=%d\n",px,nx);
if(nx==tail){
vec.push_back(make_pair(abs(a[pos].val-a[px].val),c[px]));
//cout<<abs(a[pos].val-a[px].val)<<" "<<a[px].val<<endl;
}else if(px==head){
vec.push_back(make_pair(abs(a[pos].val-a[nx].val),c[nx]));
//cout<<abs(a[pos].val-a[nx].val)<<" "<<a[nx].val<<endl;
}else if(abs(a[pos].val-a[px].val)<=abs(a[nx].val-a[pos].val)){
vec.push_back(make_pair(abs(a[pos].val-a[px].val),c[px]));
//cout<<abs(a[pos].val-a[px].val)<<" "<<a[px].val<<endl;
}else{
vec.push_back(make_pair(abs(a[pos].val-a[nx].val),c[nx]));
//cout<<abs(a[pos].val-a[nx].val)<<" "<<a[nx].val<<endl;
}
move(pos);
/*if(c[px]==0){
cout<<"reme: "<<px<<" "<<"px"<<endl;
}else if(c[nx]==0){
cout<<"reme: "<<nx<<" "<<"nx"<<endl;
}*/
}
for(int i=vec.size()-1;i>=0;i--){
cout<<vec[i].first<<" "<<vec[i].second<<endl;
}
return 0;
}
不得不说数据结构的题目写起来很繁琐。