AOJ本の読書メモ
AOJ
次のAOJの問題へ
前のAOJの問題へ
AOJ 0539 Pizza
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("8");
WillReturn.Add("3");
WillReturn.Add("2");
WillReturn.Add("3");
WillReturn.Add("1");
WillReturn.Add("4");
WillReturn.Add("6");
WillReturn.Add("20");
WillReturn.Add("4");
WillReturn.Add("4");
WillReturn.Add("12");
WillReturn.Add("8");
WillReturn.Add("16");
WillReturn.Add("7");
WillReturn.Add("7");
WillReturn.Add("11");
WillReturn.Add("8");
WillReturn.Add("0");
//3
//3
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct InputInfoDef
{
internal int D;
internal int[] DArr;
internal int[] KArr;
}
static void Main()
{
List<string> InputList = GetInputList();
var InputInfoList = new List<InputInfoDef>();
int CurrInd = 0;
while (true) {
int d = int.Parse(InputList[CurrInd]);
if (d == 0) break;
InputInfoDef WillAdd;
int n = int.Parse(InputList[CurrInd + 1]);
int m = int.Parse(InputList[CurrInd + 2]);
int StaInd1 = CurrInd + 3;
int EndInd1 = CurrInd + 3 + (n - 1) - 1;
int StaInd2 = EndInd1 + 1;
int EndInd2 = StaInd2 + m - 1;
var DList = new List<int>();
// 店舗1の分 (原点)
DList.Add(0); // 原点
DList.Add(d); // 原点(環状の対応)
for (int I = StaInd1; I <= EndInd1; I++) {
DList.Add(int.Parse(InputList[I]));
}
DList.Sort();
var KList = new List<int>();
for (int I = StaInd2; I <= EndInd2; I++) {
KList.Add(int.Parse(InputList[I]));
}
KList.Sort();
WillAdd.D = d;
WillAdd.DArr = DList.ToArray();
WillAdd.KArr = KList.ToArray();
InputInfoList.Add(WillAdd);
CurrInd = EndInd2 + 1;
}
foreach (InputInfoDef EachInputInfo in InputInfoList) {
Solve(EachInputInfo.DArr, EachInputInfo.KArr);
}
}
static void Solve(int[] pDArr, int[] pKArr)
{
long Answer = 0;
foreach (int EachK in pKArr) {
int ResultInd = ExecNibunhou(EachK, pDArr);
var KouhoList = new List<int>();
KouhoList.Add(Math.Abs(EachK - pDArr[ResultInd]));
KouhoList.Add(Math.Abs(EachK - pDArr[ResultInd + 1]));
Answer += KouhoList.Min();
}
Console.WriteLine(Answer);
}
// 二分法で、引数以下で最大の値を持つ、添字を返す
static int ExecNibunhou(int pBase, int[] pArr)
{
// 最後の要素が引数以下の特殊ケース
if (pBase >= pArr.Last()) {
return pArr.GetUpperBound(0);
}
// 最初の要素が引数未満の特殊ケース
if (pBase < pArr[0]) {
return 0;
}
int L = 0;
int R = pArr.GetUpperBound(0);
while (L + 1 < R) {
int Mid = (L + R) / 2;
if (pArr[Mid] <= pBase) {
L = Mid;
}
else {
R = Mid;
}
}
return L;
}
}
解説
注文ごとに、
二分法で、一番近い店舗を求めてます。