C♯の勉強

C♯4.0 で TopCoder の過去問を解きます。

TopCoder SRM582: SpaceWarDiv1

public class SpaceWarDiv1 {
    struct Enemy {
        public long strength, count;
    }

    public long minimalFatigue(int[] magicalGirlStrength, int[] enemyStrength, long[] enemyCount) {
        magicalGirlStrength = magicalGirlStrength.OrderByDescending(e => e).ToArray();
        var enemies = enemyStrength.Zip(enemyCount, (s, c) => new Enemy() { strength = s, count = c })
            .OrderByDescending(e => e.strength)
            .ToArray();

        long lower = 0, upper = enemies.Sum(e => e.count) + 10;
        long ans = -1;
        while (lower < upper - 1) {
            long p = (lower + upper) / 2;
            long enemyIndex = 0;
            long[] defeated = new long[enemies.Length];
            foreach (var s in magicalGirlStrength) {
                long fatigue = p;
                while (enemyIndex < enemies.Length && enemies[enemyIndex].strength <= s) {
                    long remain = enemies[enemyIndex].count - defeated[enemyIndex];
                    long use = remain - Math.Max(0, remain - fatigue);
                    defeated[enemyIndex] += use;
                    fatigue -= use;
                    if (defeated[enemyIndex] == enemies[enemyIndex].count) {
                        enemyIndex++;
                    } else {
                        break;
                    }
                }
            }
            if (enemyIndex == enemies.Length) {
                upper = p;
                ans = p;
            } else {
                lower = p;
            }
        }
        return ans;
    }
}