阿里笔试——3.25第一题100%

第一题:

大概题意:给一个3*n的数组,从每列中取出一个数,按序排列(这里当成新的数组p好了),求相邻两个数的绝对值的和的最小值。
p [ i ] p [ i 1 ] \sum |p[i]-p[i-1]|
注意一下范围: 1 n 1 e 5 1\leq n \leq1e5
一个例子:

输入:
5
5 10 5 4 4
1 7 8 4 0
3 4 9 0 3
输出:
5
解释:
序列为 5 7 5 4 4,最小值为5

个人的做题想法:
可以用res[i][j]数组记录这样的结果:观察到第j列,若当前加入序列的数是a[i][j],只需遍历前一列,即 r e s [ i ] [ j ] = min { r e s [ k ] [ j 1 ] + a b s ( a [ i ] [ j ] a [ k ] [ j 1 ] ) } 0 k 2 res[i][j]=\min \{res[k][j-1]+abs(a[i][j]-a[k][j-1])\}(0\leq k \leq 2)

for(int i=1;i<n;i++){        
	for(int j=0;j<3;j++){            
		for(int k=0;k<3;k++){
  			res[j][i]=min(res[j][i],res[k][i-1]+abs(a[j][i]-a[k][i-1]));             
        }        
    }
}

还需要注意一下初始化。
笔试时的完整代码(觉得有点丑,555):

#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 1e5+7;


int a[3][MAX_N];
int n;
long long ans;
long long res[3][MAX_N];



int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    cin >> n;
    for(int i=0;i<3;i++){
        for(int j=0;j<n;j++){
            cin >> a[i][j];
        }
    }
    //初始化
    for(int i=0;i<3;i++){
        for(int j=1;j<n;j++){
            res[i][j]=1e18;
        }
    }
    for(int i=0;i<3;i++)    res[i][0]=0;
    //主要过程
    for(int i=1;i<n;i++){
        for(int j=0;j<3;j++){
            for(int k=0;k<3;k++){

                if(a[j][i]>=a[k][i-1]){
                    if(res[j][i]>res[k][i-1]+a[j][i]-a[k][i-1])
                        res[j][i]=res[k][i-1]+a[j][i]-a[k][i-1];
                }

                else{
                    if(res[j][i]>res[k][i-1]-a[j][i]+a[k][i-1])
                        res[j][i]=res[k][i-1]-a[j][i]+a[k][i-1];
                }
            }
        }
    }
    //找最小值
    if(res[0][n-1]<res[1][n-1])    ans=res[0][n-1];
    else    ans=res[1][n-1];
    if(res[2][n-1]<ans)    ans=res[2][n-1];
    cout << ans;
    return 0;
}

做题的时候有点慌,有点手误,耽误了时间。积累经验吧!

发布了2 篇原创文章 · 获赞 4 · 访问量 88

猜你喜欢

转载自blog.csdn.net/weixin_41923381/article/details/105104772