AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC256-D Union of Interval
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");
WillReturn.Add("10 20");
WillReturn.Add("20 30");
WillReturn.Add("40 50");
//10 30
//40 50
}
else if (InputPattern == "Input2") {
WillReturn.Add("3");
WillReturn.Add("10 40");
WillReturn.Add("30 60");
WillReturn.Add("20 50");
//10 60
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct RangeInfo
{
internal int RangeSta;
internal int RangeEnd;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
var RangeInfoList = new List<RangeInfo>();
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
RangeInfo WillAdd;
WillAdd.RangeSta = wkArr[0];
WillAdd.RangeEnd = wkArr[1];
RangeInfoList.Add(WillAdd);
}
var Query = DeriveMergedRangeList(RangeInfoList);
foreach (RangeInfo EachRangeInfo in Query) {
Console.WriteLine("{0} {1}", EachRangeInfo.RangeSta, EachRangeInfo.RangeEnd);
}
}
// 閉区間の列挙を引数として、
// OverLapした閉区間をマージした列挙を返す
static IEnumerable<RangeInfo> DeriveMergedRangeList(IEnumerable<RangeInfo> pRangeInfoEnum)
{
RangeInfo[] RangeInfoArr = pRangeInfoEnum.OrderBy(px => px.RangeSta).ToArray();
int MergedRangeSta = RangeInfoArr[0].RangeSta;
int MergedRangeEnd = RangeInfoArr[0].RangeEnd;
int UB = RangeInfoArr.GetUpperBound(0);
for (int I = 0; I <= UB; I++) {
int CurrRangeSta = RangeInfoArr[I].RangeSta;
int CurrRangeEnd = RangeInfoArr[I].RangeEnd;
if (CurrRangeSta <= MergedRangeEnd && MergedRangeSta <= CurrRangeEnd) {
// 今の区間とオーバーラップしてる場合
MergedRangeEnd = Math.Max(MergedRangeEnd, CurrRangeEnd);
}
else {
// 今の区間とオーバーラップしてない場合
yield return new RangeInfo() { RangeSta = MergedRangeSta, RangeEnd = MergedRangeEnd };
MergedRangeSta = CurrRangeSta;
MergedRangeEnd = CurrRangeEnd;
}
if (I == UB) {
yield return new RangeInfo() { RangeSta = MergedRangeSta, RangeEnd = MergedRangeEnd };
}
}
}
}
解説
区間をStaの昇順にソートしてから
順に区間を見てます。