Google Kick Start 2019 (March) "Training"

Quiz

https://codingcompetitions.withgoogle.com/kickstart/round/0000000000050e01/00000000000698d6

Google Kick Start?

  • GCJほどではなくAtCoder ABCのような気軽に参加できるコンペティションのようだ
  • 月イチで予定されている
  • 最初の問題 "Training" を解いてみた

解法

  • ソートして累積和(またはしゃくとり法)
  • Pの幅で全探索
    • メンバーの強さは(Pの範囲内の)右端に合わせる必要がある
    • 他のメンバーを右端と同じ高さになるまでcoachする
  • O(N)
  • テストケースの数も合わせるとO(N * T) = 107 となり間に合う

f:id:peroon:20190325054605j:plain

Code

#include<algorithm>
#include<complex>
#include<ctype.h>
#include<iomanip>
#include<iostream>
#include<fstream>
#include<map>
#include<math.h>
#include<numeric>
#include<queue>
#include<set>
#include<stack>
#include<stdio.h>
#include<string>
#include<string>
#include<vector>

using namespace std;
typedef long long ll;

#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define ALL(v) (v).begin(), (v).end()
#define p(s) cout<<(s)<<endl
#define p2(s, t) cout << (s) << " " << (t) << endl
#define br() p("")
#define pn(s) cout << (#s) << " " << (s) << endl
#define p_yes() p("Yes")
#define p_no() p("No")

const ll mod = 1e9 + 7;
const ll inf = 1e18;

template < typename T >
void vprint(T &V){
    for(auto v : V){
        cout << v << " ";
    }
    cout << endl;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    // input
    ll T;
    cin >> T;

    
    FOR(t, 0, T){
        ll N, P;
        cin >> N >> P;

        vector<ll> A(N);
        FOR(i, 0, N){
            cin >> A[i];
        }
        sort(ALL(A));

        ll sum = 0;
        FOR(i, 0, P){
            sum += A[i];
        }
        ll min_cost = A[P-1] * P - sum;

        // しゃくとり
        FOR(i, 1, N-P+1){
            sum -= A[i-1];
            sum += A[i-1+P];

            ll cost = A[i-1+P] * P - sum;
            min_cost = min(min_cost, cost);
        }

        cout << "Case #" << t+1 << ": " << min_cost << endl;
    }
    
    return 0;
}