2023年牛客暑假多校-1 -H.Matches

题目描述

Walk Alone has two rows of matches, each of which contains n matches. He defines the distance between them as d=\sum_{i=1}^{n}\left | a_i - b_i \right |, where a_i​ and b_i​ represent the height of the i-th match in the first row and the second row, respectively. Walk Alone wants to beautify the matches by shortening the distance, and you are asked to find out the minimum distance after performing at most one swap within one row. Note that the height can be negative.

输入描述

The first line contains one integer n(1\leq n \leq 10^6), denoting the number of matches in each row.

The second and the third line both contains n integers, representing the height of matches in the first row and the second row, respectively. All of these numbers satisfy \left | a_i \right |, \left | b_i \right | \leq 10^9.

输出描述

Print one line containing a single integer, the minimum distance you can get.

样例

输入:

3
1 2 3
3 2 1

输出:

0

输入:

4
4 3 9 9
7 3 7 3

输出:

5

样例解释:

In the second example, one of the best strategies is to swap a1​ and a4, and the minimum distance is |9−7|+|3−3|+|9−7|+|4−3|=5|9−7|+|3−3|+|9−7|+|4−3|=5.

题目大意:

给定两个数组a,b,通过交换a或者交换b中的某个数,求能得到  d=\sum_{i=1}^{n}\left | a_i - b_i \right | 的最小值

思路:

2023年牛客暑假多校-1 -H.Matches_第1张图片

这样就可以得出将反序包络转化成正序不交,将反序相交转化成反序不交是有意义的,正序转正序没有意义

所以我们先来枚举一边数据,找到正序的最大值和反序的最大值(可以参考以下代码,我找的反序最大值不一定是反序的,如果全部为正序的话,他找到的是正序最小的;同理我找到的也可能全部为反序,存正序最大的就变成了反序最小)

下面在枚举一边数组,如果是正序就取跟反序的最大的尝试交换,如果是反序就跟正序的最大尝试交换(原因可以根据上图来进行理解),这样我就把所有得到情况交换之后,取交换后能得到的最小的值输出即可

代码:

#include
using namespace std;
typedef long long ll;
const int N = 1e6+10;
ll a[N];
ll b[N];
ll sum;
ll jiaohuan(ll x,ll y,ll ans){
    ans -= abs(a[x] - b[x]) + abs(a[y] - b[y]);
    ans += abs(a[x] - b[y]) + abs(a[y] - b[x]);
    return ans;
}
int main()
{
    ll n;
    cin >> n;
    for(int i = 1;i <= n;i++){
        cin >> a[i];
    }
    for(int i = 1;i <= n;i++){
        cin >> b[i];
    }
    ll minn = 1;
    ll minn2 = 1;
    for(int i = 1;i <= n;i++){
        sum += abs(a[i] - b[i]);
        if(a[i]-b[i] > a[minn] - b[minn]){
            minn = i;
        }
        if(a[i] - b[i] < a[minn2] - b[minn2]){
            minn2 = i;
        }
    }
    ll ans = sum;
    // cout << sum << " " << minn << endl;
    for(int i = 1;i <= n;i++){
        if(a[i] - b[i] < 0){
            sum = min(sum, jiaohuan(i,minn,ans));
        }
        else{
            sum = min(sum,jiaohuan(i,minn2,ans));
        }
    }
    cout << sum;
}

 

你可能感兴趣的:(算法,c++,c语言,数据结构)