Codeforces Round 969 (Div. 2) C. Dora and C++ (裴蜀定理)

Codeforces Round 969 (Div. 2) C. Dora and C++ (裴蜀定理)_第1张图片
什么?竟然是裴蜀定理。。。


由于这里给出了a和b两个数,我们或许可以想到使用同样是需要给出两个定值的裴蜀定理,即:

  • 如果给定 x x x y y y,那么一定有 a x + b y = g c d ( x , y ) ax+by=gcd(x,y) ax+by=gcd(x,y)

所以在这时候我们就可以让输入的所有数都去对 g c d ( a , b ) gcd(a,b) gcd(a,b)取模,这样就能够得到所有数的最简形式(可以当成是让所有数尽可能消去 a a a b b b的组成)。

至于这里为什么能减:

  • 虽然这里给我们的条件是只能够加,但是一个数加了就相当于其他数都在减,所以我们可以直接将其转化为减操作。

那么在取模之后我们现在排序,得到的极差就是 c [ n ] − c [ 1 ] c[n] - c[1] c[n]c[1],那么这里我们还要进行一次 o ( n ) o(n) o(n)的判断,因为不排除有这种情况存在 c [ i ] + g − c [ i − 1 ] < c [ n ] − c [ 1 ] c[i] + g - c[i-1] < c[n] - c[1] c[i]+gc[i1]<c[n]c[1],这样我们会取到最优解。

void solve()
{
    int n,a,b;cin >> n >> a >> b;
    int g = __gcd(a,b);
    vector<int>c(n);
    for(int i = 0;i < n;i++){
        cin >> c[i];
        c[i]%=g;
    }

    sort(c.begin(),c.end());

    int res = c[n-1] - c[0];

    for(int i = 1;i < n;i++){
        res = min(res,c[i] + g - c[i-1]);
    }

    cout << res << endl;
}

你可能感兴趣的:(刷题记录,c语言,c++,开发语言)