ないものは作りましょう。

色々なことに挑戦(主にプログラミング)

Google Code Jam 2015 Round1Aに参加しました

結果はA-small + A-large + B-small = 26pts 2761位でした。
Round1B,Cで頑張ろうと思います。
f:id:IJMP320:20150418132005p:plain

Problem A「Mushroom Monster」

10秒間隔で皿に乗っているマッシュルームの個数が与えられて、2通りの方法で、食べたマッシュルームの個数の最小値を計算する問題。1番目は各時間で食べられる個数が自由な場合で、2番目は10秒間に一定数のマッシュルームを食べる場合です。
どちらもシミュレーションで解きました。1番目の方法は各時間のマッシュルームの個数の差をとって足すだけです。
2番目の方法では減っている個数の最大値が10秒間に食べる個数です。

ll mx(ll a, ll b) {
    return (a > b ? a : b);
}

int main() {
    int T;
    cin >> T;
    REP(t,T) {
        int n;
        cin >> n;
        vector<ll> m(n);
        REP(i,n) cin >> m[i];

        ll y=0,z=0;
        ll s=0;
        FOR(i,1,n) {
            y += mx(0, m[i-1] - m[i]);
            s = mx(s,m[i-1]-m[i]);
        }

        FOR(i,0,n-1) {
            z += (m[i]>s ? s : m[i]);
        }
        printf("Case #%d: %lld %lld\n",t+1,y,z);
    }
    return 0;
}

Problem B「Haircut」

※Smallしか解けない解法です(二分探索思いつかなかった)
N人目の客がどの理容師に髪を切ってもらうが求める問題。Nの制約が10^9であることに注意。
紙に書いてみると周期があることに気が付きました。周期は理容師の必要な時間の最小公倍数で求まります。その周期の範囲で何番目の客がどの理容師に当たるのかを求め、(N % 周期中の客の人数)番目を参照する、みたいな感じで解きました。

int gcd(int a, int b) {
    if(a<b) swap(a,b);
    while (b) {
        int t = a % b;
        a = b;
        b = t;
    }
    return a;
}

int lcm(int a, int b) {
    return a / gcd(a,b) * b;
}

int lcm_n(vector<int> &numbers) {
    int l;
    l = numbers[0];
    for (int i = 1; i < numbers.size(); i++) {
        l = lcm(l, numbers[i]);
    }
    return l;
}

int main() {
    int T;
    cin >> T;
    REP(t,T) {
        int B,N;
        cin >> B >> N;
        vector<int> m(B);
        REP(i,B) cin >> m[i];

        int l = lcm_n(m);

        vector<int> a(1,-1);
        for(ll i=0;i<l;i++) {
            REP(j,B) {
                if(i % m[j] == 0) {
                    a.PB(j+1);
                }
            }
        }
        int k = (N % (a.size()-1));
        if(k==0) k=a.size()-1;
        int ans = a[k];
        printf("Case #%d: %d\n",t+1,ans);
    }
    return 0;
}