一个索引数组的解法
查看原帖
一个索引数组的解法
1481592
qfcy楼主2024/11/21 15:29

前几篇的平衡树题解,个人觉得有点复杂。
这是没有用到平衡树的题解,来个排序的:

#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;

int main(){
    cin.sync_with_stdio(false);
    int n;cin>>n;
    int *a=new int[n];
    for(int i=0;i<n;i++)cin>>a[i];
    int *order=new int[n]; // 索引数组,排序后的a
    int *idx=new int[n]; // 每个a的索引在order中出现的位置
    for(int i=0;i<n;i++)order[i]=i;
    //for(int i=0;i<n-1;i++){
    //    for(int j=0;j<n-i-1;j++){
    //        if(a[order[j]]>a[order[j+1]])swap(order[j],order[j+1]);
    //    }
    //}
    sort(order, order+n, [&a](int m, int n) {
        return a[m]<a[n]; // 升序
    });
    for(int i=0;i<n;i++)idx[order[i]]=i;

    long long total=a[0];
    for(int i=1;i<n;i++){ //i:a的索引
        int min_dt_l=INT_MAX,min_dt_r=INT_MAX;
        int index=idx[i]; //index:idx中i元素对应的索引
        int l=index-1,r=index+1; // l,r:idx的索引
        while(l>=0 || r<n){
            // 需要同时找到左边和右边的最小波动值
            if(l>=0){
                int idx_l=order[l]; //idx_l,idx_r:a的索引
                if(idx_l<i) // 如果时间在i前面
                    min_dt_l=min(min_dt_l,a[i]-a[idx_l]);
            }
            if(r<n){
                int idx_r=order[r];
                if(idx_r<i)
                    min_dt_r=min(min_dt_r,a[idx_r]-a[i]);
            }
            if((l<0 || min_dt_l!=INT_MAX) && (r>=n || min_dt_r!=INT_MAX))break;
            if(l>=0)l--;
            if(r<n)r++;
        }
        int min_dt=min(min_dt_l,min_dt_r);
        total+=min_dt;
    }
    cout<<total<<endl;
    return 0;
}
2024/11/21 15:29
加载中...