C-操作数组

牛客小白月赛 72C 题
题目链接
题目描述:

给定两个长度为 n n n的数组 a a a b b b(下标从 1 1 1开始),你的目标是使 a = b a = b a=b,为了完成你的目标,你可以执行以下操作任意次(也可以是 0 0 0次):
选择两个正整数 i , j i,j i,j,满足 1 ≤ i , j ≤ n 1 \leq i,j \leq n 1i,jn i ≠ j i \neq j i=j,使 a i 变成 a i − 1 a_i变成a_i-1 ai变成ai1, a j a_j aj变成 a j + 1 a_j+1 aj+1
尽管你可以执行任意次操作,但这里求的是最小操作次数,如果无论如何都不能使 a = b a = b a=b,请报告。

输入描述:

第一行包含一个正整数 n n n( 2 ≤ n ≤ 1 0 5 2\leq n \leq 10^5 2n105), n n n表示数组的长度。
第二行包含n个正整数 a 1 , a 2 , . . . , a n ( 1 ≤ a i ≤ 1 0 9 ) a_1,a_2,...,a_n(1 \leq a_i \leq 10^9) a1,a2,...,an(1ai109)
第三行包含 n n n个正整数 b 1 , b 2 , . . . , b n ( 1 ≤ b i ≤ 1 0 9 ) b_1,b_2,...,b_n(1 \leq b_i \leq 10^9) b1,b2,...,bn(1bi109)

输出描述:

输出包含一个整数,表示最小操作次数。如果无论如何都不能使 a = b a=b a=b,输出-1.

示例1
输入

4
1 2 3 4
4 3 2 1

输出

4

解题思路:

思路一:看两个数组对应位置的差值,如果差值和为0,那么就可以,如果不是就不行,将差值为正的或为负的加起来就是答案
思路二:将两个数组的平均数相比(因为数组长度相等,那么只用比数组的各数字之和是否相等即可),如果不等就不行,如果相等依旧是将不相等的差值加起来,取绝对值再最后除二即可

下面给出思路一的推出过程,思路二其实本质类似:

因为操作是选择两个不同的数,一个加一一个减一,那么如果可以操作,那和另一个数组相比,如果差值n有x个,那么差值-n一定也有x个,那么就可以操作x次将这两个数变成符合题意的情况,所以只需要记录差值n的有多少个,差值-n的有多少个,这时候想到用数组去记,然后去挨个比较是否相等。
但有一种情况,如果差值n的有x个,差值n+a的有y个, 但差值-n和n+a的分别没有x个和y个,其实也是可以的,我们只需要保证nx+(n+a)y==(-n)( x 2 x_2 x2)+(n+a)( y 2 y_2 y2)即可。
样例:3
1 4 6
2 5 4
答案是2
但差值-1的有两个而差值1的没有,反而差值2的有一个。
那么思路就很明显了,只需要保证差值为负的和的绝对值等于差值为正的和即可!

思路1:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int all;
int suma,sumb;
int cha;
void sove(void){
    int n;cin>>n;
    int a[n],b[n];
    for(int i=0;i<n;i++){scanf("%lld",&a[i]);}
    for(int i=0;i<n;i++){scanf("%lld",&b[i]);cha+=a[i]-b[i];if(a[i]-b[i]>0)all+=a[i]-b[i];}
    if(cha==0){
        cout<<all;
    }
    else cout<<-1;
    
}
signed main(void){
    int _=1;
    //cin>>_;
    while(_--){
        sove();
    }
    return 0;
}

思路二:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int all;
int suma,sumb;
void sove(void){
    int n;cin>>n;
    int a[n],b[n];
    for(int i=0;i<n;i++){scanf("%lld",&a[i]);suma+=a[i];}
    for(int i=0;i<n;i++){scanf("%lld",&b[i]);if(a[i]!=b[i])all+=abs(a[i]-b[i]);sumb+=b[i];}
    if(suma==sumb)
    cout<<all/2;
    else cout<<-1;
}
signed main(void){
    int _=1;
    //cin>>_;
    while(_--){
        sove();
    }
    return 0;
}

记得开long long,并且如果有scanf("%d",& )的时候改成"%lld"

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值