AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC172-A Chocolate
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("4 4 4");
WillReturn.Add("1 0 0 1");
//Yes
}
else if (InputPattern == "Input2") {
WillReturn.Add("5 7 6");
WillReturn.Add("0 1 0 2 0 1");
//Yes
}
else if (InputPattern == "Input3") {
WillReturn.Add("3 2 7");
WillReturn.Add("0 0 0 0 0 0 0");
//No
}
else if (InputPattern == "Input4") {
WillReturn.Add("11 11 2");
WillReturn.Add("2 3");
//No
}
else if (InputPattern == "Input5") {
WillReturn.Add("777 777 6");
WillReturn.Add("8 6 9 1 2 0");
//Yes
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct RectDef
{
internal long Width;
internal long Height;
}
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
long H = wkArr[0];
long W = wkArr[1];
long[] AArr = InputList[1].Split(' ').Select(pX => long.Parse(pX)).ToArray();
for (long I = 0; I <= AArr.GetUpperBound(0); I++) {
AArr[I] = (long)(1 << (int)AArr[I]);
}
AArr = AArr.OrderByDescending(pX => pX).ToArray();
var RectList = new List<RectDef>();
RectDef WillAdd;
WillAdd.Width = W;
WillAdd.Height = H;
RectList.Add(WillAdd);
foreach (long EachA in AArr) {
bool IsOK = false;
for (int I = 0; I <= RectList.Count - 1; I++) {
RectDef CurrRect = RectList[I];
if (CurrRect.Width < EachA) continue;
if (CurrRect.Height < EachA) continue;
var AddRectList = new List<RectDef>();
Action AddAct = () =>
{
long RestWidth = CurrRect.Width - EachA;
long RestHeight = CurrRect.Height - EachA;
if (RestWidth == 0 && RestHeight == 0) return;
if (RestWidth > 0 && RestHeight == 0) {
WillAdd.Width = RestWidth;
WillAdd.Height = EachA;
RectList.Add(WillAdd);
return;
}
if (RestWidth == 0 && RestHeight > 0) {
WillAdd.Width = EachA;
WillAdd.Height = RestHeight;
RectList.Add(WillAdd);
return;
}
if (RestWidth >= RestHeight) {
// 右の分を追加
WillAdd.Width = RestWidth;
WillAdd.Height = CurrRect.Height;
RectList.Add(WillAdd);
// 下の分を追加
WillAdd.Width = EachA;
WillAdd.Height = RestHeight;
RectList.Add(WillAdd);
}
else {
// 下の分を追加
WillAdd.Width = CurrRect.Width;
WillAdd.Height = RestHeight;
RectList.Add(WillAdd);
// 右の分を追加
WillAdd.Width = RestWidth;
WillAdd.Height = EachA;
RectList.Add(WillAdd);
}
};
AddAct();
IsOK = true;
RectList.RemoveAt(I);
RectList.AddRange(AddRectList);
break;
}
if (IsOK == false) {
Console.WriteLine("No");
return;
}
}
Console.WriteLine("Yes");
}
}
解説
正方形の大きさの降順に敷き詰めます。
敷き詰める場合は、必ず長方形の左上から敷き詰めます。
正方形を敷き詰めるので、
残ったピースは、長方形のListで管理します。
下記のように
3*3の正方形を敷き詰めたら、
長さが3でないほうの辺の長いほう(この場合はBの長方形)が
Cの長方形を持つようにします。
こうしないと、2*2の正方形の敷き詰め可能数が減ってしまうので
■■■A
■■■A
■■■A
BBBC
BBBC