AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC176-A 01 Matrix Again
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 2");
WillReturn.Add("1 4");
WillReturn.Add("3 2");
//8
//1 2
//1 4
//2 1
//2 4
//3 2
//3 3
//4 1
//4 3
}
else if (InputPattern == "Input2") {
WillReturn.Add("3 3");
WillReturn.Add("3 1");
WillReturn.Add("2 3");
WillReturn.Add("1 3");
//9
//1 1
//1 2
//1 3
//2 1
//2 2
//2 3
//3 1
//3 2
//3 3
}
else if (InputPattern == "Input3") {
WillReturn.Add("7 3");
WillReturn.Add("1 7");
WillReturn.Add("7 6");
WillReturn.Add("6 1");
//21
//1 6
//2 4
//4 1
//7 3
//3 6
//4 5
//6 1
//1 7
//7 6
//3 5
//2 2
//6 3
//6 7
//5 4
//5 2
//2 5
//5 3
//1 4
//7 1
//4 7
//3 2
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long mN;
static long mM;
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();
SplitAct(InputList[0]);
mN = wkArr[0];
mM = wkArr[1];
var PosSet = new HashSet<long>();
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
long CurrY = wkArr[0];
long CurrX = wkArr[1];
long Hash = GetHash(CurrX, CurrY);
PosSet.Add(Hash);
}
// ------------------------------------------------------------
// 01 斜めのラインに追加
// ------------------------------------------------------------
foreach (long EachHash in PosSet.ToArray()) {
long CurrX = EachHash / 1000000;
long CurrY = EachHash % 1000000;
for (long LoopCnt = 1; LoopCnt <= mN; LoopCnt++) {
if (++CurrX > mN) CurrX = 1;
if (--CurrY < 1) CurrY = mN;
long CurrHash = GetHash(CurrX, CurrY);
if (PosSet.Add(CurrHash) == false) break;
}
}
// ------------------------------------------------------------
// 02 不足分を追加
// ------------------------------------------------------------
long RestCnt = mN * mM - PosSet.Count;
for (long LoopX = 1; LoopX <= mN; LoopX++) {
if (RestCnt == 0) break;
long CurrX = LoopX;
long CurrY = 1;
long CurrHash = GetHash(CurrX, CurrY);
if (PosSet.Contains(CurrHash) == false) {
for (long LoopCnt = 1; LoopCnt <= mN; LoopCnt++) {
if (++CurrX > mN) CurrX = 1;
if (--CurrY < 1) CurrY = mN;
CurrHash = GetHash(CurrX, CurrY);
if (PosSet.Add(CurrHash) == false) break;
RestCnt--;
}
}
}
// ------------------------------------------------------------
// 03 解を出力
// ------------------------------------------------------------
var sb = new System.Text.StringBuilder();
sb.Append(PosSet.Count);
sb.AppendLine();
foreach (long EachHash in PosSet) {
long CurrX = EachHash / 1000000;
long CurrY = EachHash % 1000000;
sb.AppendFormat("{0} {1}", CurrY, CurrX);
sb.AppendLine();
}
Console.Write(sb.ToString());
}
static long GetHash(long pX, long pY)
{
return pX * 1000000 + pY;
}
}
解説
□□□●
□□●□
□●□□
●□□□
のように斜めライン1つで
全ての列と、全ての行の
●を1増やすことができます。
なので
初期配置の●の分の斜めラインを最初に引く。
それでも、●が不足してたら
任意の斜めラインに●を配置する。
というロジックで解けます。