AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC133-C Row Column Sums
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("2 4 3");
WillReturn.Add("0 2");
WillReturn.Add("1 2 2 0");
//11
}
else if (InputPattern == "Input2") {
WillReturn.Add("3 3 4");
WillReturn.Add("0 1 2");
WillReturn.Add("1 2 3");
//-1
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long mH;
static long mW;
static long mK;
static long[] mYokoSumArr;
static long[] mTateSumArr;
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
mH = wkArr[0];
mW = wkArr[1];
mK = wkArr[2];
mYokoSumArr = InputList[1].Split(' ').Select(pX => long.Parse(pX)).ToArray();
mTateSumArr = InputList[2].Split(' ').Select(pX => long.Parse(pX)).ToArray();
// 横計と縦計がmod k で不一致なら不可
long YokoSumMod = 0;
Array.ForEach(mYokoSumArr, pX =>
{
YokoSumMod += pX;
YokoSumMod %= mK;
});
long TateSumMod = 0;
Array.ForEach(mTateSumArr, pX =>
{
TateSumMod += pX;
TateSumMod %= mK;
});
if (YokoSumMod != TateSumMod) {
Console.WriteLine(-1);
return;
}
long YokoSumReal = 0;
foreach (long EachYokoSum in mYokoSumArr) {
long ProdVal = (mK - 1) * mW;
long MinusVal = Solve(ProdVal, EachYokoSum);
YokoSumReal += ProdVal - MinusVal;
}
long TateSumReal = 0;
foreach (long EachTateSum in mTateSumArr) {
long ProdVal = (mK - 1) * mH;
long MinusVal = Solve(ProdVal, EachTateSum);
TateSumReal += ProdVal - MinusVal;
}
Console.WriteLine(Math.Min(YokoSumReal, TateSumReal));
}
// 合同方程式 A - ? ≡ B mod K
// の ? を返す
static long Solve(long pA, long pB)
{
pA %= mK;
pB %= mK;
long Answer = pA - pB;
Answer %= mK;
if (Answer < 0) Answer += mK;
return Answer;
}
}
解説
□□□□0
□□□□2
2201
の入力例で考えます。
必要条件として、
横計の総合計と
縦計の総合計が
mod k で見て不一致なら、解なしとなります。
mod k ではなく実際の和での最大値を考えると
(k-2) * マス目の数 - ? ≡ 縦計または横計 mod k
の合同方程式で、横計と縦計の最大値を求めることができます。
横計と縦計の2つの最大値の中で
小さいほうを調整により達成可能なので
これが解になります。