Translate 【gcd 妙用】

题目描述
你N个正整数a[1]…a[N],在最初的时候,你选择一个正整数X,然后以后每一步,你可以使一个数a[i] 变成 a[i] + X,或者 a[i] - X,聪明的你,一定会知道怎么选择这个X,使得最后所有的数都变成相等,而且使用的变化步数最少。

输入
多组测试数据。对于每组数据,一个N(2 <= N <= 1000),接下来一行有N个数a[1]…a[N] (1 <= a[i] <= 10^6)。

保证这N个数不全相等。

输出
每组数据单独一行,你找出的正整数X,以及最少步数,两个数用一个空格隔开.

样例输入
3
1 2 3
4
3 5 7 11
样例输出
1 2
2 5
来源
BoilTask

#include<iostream>
#include<queue>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<stdio.h>
#define LL long long
using namespace std;
const int MAXN = 1e3+10;
const int MAXM = 1e6+100;
const int inf = 0x3f3f3f3f;
/*------------------------------*/
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}

int arr[MAXN];
int brr[MAXM];
int main(){
    int n,m;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++)
            scanf("%d",&arr[i]);
   // 这里找到的是任意两个之间的差值的 gcd。 (1)
        int val=abs(arr[1]-arr[2]);
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++){
            val=gcd(val,abs(arr[i]-arr[j]));
        }
         sort(arr+1,arr+1+n);

  /*   (2) 别人的题解  。
     sort(arr+1,arr+n+1);
        for(int i=2;i<=n;i++)
            brr[i-1]=arr[i]-arr[i-1];
        int val=brr[1];
        for(int i=2;i<=n-1;i++)
            val=gcd(val,brr[i]);
*/
             if(n&1) {
                int k=(n+1)/2;
                int cnt=0;
                for(int i=1;i<=n;i++){
                    cnt+=abs(arr[i]-arr[k])/val;
                }
                printf("%d %d\n",val,cnt);
             }
             else {
               int k=n/2;
                int cnt=0;
                for(int i=1;i<=n;i++){
                    cnt+=abs(arr[i]-arr[k])/val;
                }

               int l=0;k++;
                for(int i=1;i<=n;i++){
                    l+=abs(arr[i]-arr[k])/val;
                }
                printf("%d %d\n",val,min(l,cnt));
             }
        }
    return 0;
}

看了上部分的 (1)和(2),我就是无法理解别人的解,为什么只要求排序后的n-1个差值的gcd就可以满足题意,想了半天才想到。
假如一个排序好的 三个数 A B C 【由小到大】
x=gcd(B-A , C-B) y =gcd(B-A , C-B , C-A );
实际意义就是 x*n=B-A ,x*m=C-B . 如果这样的话, 那么x*(n+m) =C-A … 所以得证 x==y 。所以排好序,找n-1个差值的gcd就足够了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值