AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC227-D Project Planning
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3 3");
WillReturn.Add("2 3 4");
//2
}
else if (InputPattern == "Input2") {
WillReturn.Add("4 2");
WillReturn.Add("1 1 3 4");
//4
}
else if (InputPattern == "Input3") {
WillReturn.Add("4 3");
WillReturn.Add("1 1 3 4");
//2
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long[] mAArr;
static long mK;
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
mK = wkArr[1];
mAArr = InputList[1].Split(' ').Select(pX => long.Parse(pX)).ToArray();
long L = 1;
long R = mAArr.Sum() / mK + 1;
while (L + 1 < R) {
long Mid = (L + R) / 2;
if (CanCreateGroup(Mid)) {
L = Mid;
}
else {
R = Mid;
}
}
Console.WriteLine(L);
}
// K人のグループをXグループ作れるかを判定
static bool CanCreateGroup(long pX)
{
long UB = mAArr.GetUpperBound(0);
long SumVal = 0;
for (long I = 0; I <= UB; I++) {
SumVal += Math.Min(mAArr[I], pX);
if (SumVal >= pX * mK) return true;
}
return false;
}
}
解説
1人、2人、2人、6人、7人の
グループがあるとして、3プロジェクト作れるかを判定するには
図で考えて
グループ1 □
グループ2 □□
グループ3 □□
グループ4 □□□□□□
グループ5 □□□□□□□
3プロジェクトなので、4人以上いるグループは、
3人しかいないとみなせて、図を変更します。
グループ1 □
グループ2 □□
グループ3 □□
グループ4 □□□
グループ5 □□□
後は、プライオリティキューを使って、
最大人数から1人ずつ取っていくと考えれば
人数合計 <= 作るプロジェクト数 * 1プロジェクトの人数
を満たすかで判定できます。
判定メソッドを作れるので、二分法で解けます。