AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC224-B Adjacent Tiles
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("6");
WillReturn.Add("1");
WillReturn.Add("2");
WillReturn.Add("3");
WillReturn.Add("4");
WillReturn.Add("100000000000000000");
WillReturn.Add("1000000000000000000");
//0
//1
//2
//4
//199999999367544467
//1999999998000000000
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long[] GetSplitArr(string pStr)
{
return (pStr == "" ? new string[0] : pStr.Split(' ')).Select(pX => long.Parse(pX)).ToArray();
}
static void Main()
{
List<string> InputList = GetInputList();
for (int I = 1; I <= InputList.Count - 1; I++) {
long N = long.Parse(InputList[I]);
long Answer = Solve(N);
Console.WriteLine(Answer);
}
}
static long Solve(long pN)
{
if (pN == 1) return 0;
if (pN == 2) return 1;
if (pN == 3) return 2;
if (pN == 4) return 4;
long L = 0;
long R = pN;
long AnswerSum = 0;
while (L + 1 < R) {
long Mid = (L + R) / 2;
long Sum;
if (CanAchieve(pN, Mid, out Sum)) {
AnswerSum = Sum;
L = Mid;
}
else {
R = Mid;
}
}
return AnswerSum;
}
// 2をX個以上作成可能か?
// 作成可能なら解候補をpSumに設定
static bool CanAchieve(long pN, long pX, out long pSum)
{
pSum = 0;
long Rest = pN - pX;
if (Rest <= 3) return false;
// 0の分を引く
Rest--;
long Yoko;
long Tate;
if (Rest % 2 == 0) {
Yoko = Rest / 2;
Tate = Rest / 2;
}
else {
Yoko = Rest / 2;
Tate = Rest - Yoko;
}
if (WillOverProd(Yoko, Tate, long.MaxValue) || Yoko * Tate >= pX) {
// 1の数
long CntOne = Yoko + Tate;
// 2の数
long CntTwo = pX;
pSum = CntOne + CntTwo * 2;
return true;
}
return false;
}
// long型の2正数の掛け算が、Limitを超えるかを返す
static bool WillOverProd(long pA, long pB, long pLimit)
{
return pA > pLimit / pB;
}
}
解説
対称性より、
左か下のみに伸ばせるとしても、解は変わらないです。
なので
0111
1222
1222
1222
のような寄与度の図で、2をたくさん作るのが最適です。
そして、作る2の数を決めたら、
残った中で0と1を作ることになり、
横の長さと、縦の長さの和が決まった状態で、
作成可能な最大面積の長方形を考える問題となり、
これは、横の長さと縦の長さの差を最小化するのが最適です。
以上により、作る2の数を二分探索して解くことができます。