读题

由题意知道,最终只能减到0。那么可将最小值代表为0,其他值减去最小值。接下来获取最大的k,k满足能将每个数减到0。

场上思路

既然k可能成立,也可能不成立,那么可以从a[i]的范围出发进行二分,如果这个k能成立,那么就贪心的向大走。

反思

场上思路没有考虑到k不存在充分性。换言之,代码无法实现,因为某个数不成立时,它的左边和右边可能都有能成立的k。

解题思路

由于数组a中的每个值最终都会变成最小值,考虑到使用a[i]-a[i-1]消除最小值的影响(联想拔苗助长

容易发现减去的最大值是差值的最大公约数,而algorithm中的__gcd(a,b)可求a与b的最大公约数,且在b=0时输出a,可解决此问题。


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int n,a[50];
bool isOk(){
    for(int i=1;i<=n;i++){
        if(a[i]!=a[1])return false;
    }
    return true;
}
int main(){
    int T;
    cin>>T;
    while(T--){
        cin>>n;
        int minn=10000000;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            minn=min(minn,a[i]);
        }
        if(isOk()){
            printf("-1\n");
            continue;
        }
        int tmp;
        for(int i=1;i<=n;i++){
            a[i]-=minn;
            if(a[i]!=0)tmp=a[i];
        }
        for(int i=1;i<=n;i++){
            tmp=__gcd(tmp,a[i]);
        }
        printf("%d\n",tmp);
    }
    return 0;
}
View Code