トップページに戻る
次の増井さんの書籍の問題へ
前の増井さんの書籍の問題へ
Q49 反転で作る互い違い
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
Solve(3);
Solve(8);
}
struct JyoutaiDef
{
internal int CurrP;
internal bool[] IsBlackArr;
internal List<bool[]> Log;
}
static void Solve(int pN)
{
var que = new Queue<JyoutaiDef>();
JyoutaiDef WillEnqueue;
WillEnqueue.CurrP = 0;
WillEnqueue.IsBlackArr = new bool[pN * 2];
int UB = WillEnqueue.IsBlackArr.GetUpperBound(0);
for (int I = 0; I <= pN - 1; I++)
WillEnqueue.IsBlackArr[I] = true;
WillEnqueue.Log = new List<bool[]>() { WillEnqueue.IsBlackArr };
que.Enqueue(WillEnqueue);
while (que.Count > 0) {
JyoutaiDef Dequeued = que.Dequeue();
//クリア判定
if (IsClear(UB, Dequeued.IsBlackArr)) {
Console.WriteLine("n={0}での解を発見", pN);
for (int I = 0; I <= Dequeued.Log.Count - 1; I++) {
Console.WriteLine("{0}手目", I);
Array.ForEach(Dequeued.Log[I], X => Console.Write(X ? '■' : '□'));
Console.WriteLine();
}
return;
}
for (int I = Dequeued.CurrP; I <= UB; I++) {
WillEnqueue.CurrP = I + 1;
WillEnqueue.IsBlackArr = (bool[])Dequeued.IsBlackArr.Clone();
for (int J = 0; J <= 2; J++) {
int wkInd = I + J;
if (wkInd > UB) {
wkInd -= (UB + 1);
}
WillEnqueue.IsBlackArr[wkInd] = !WillEnqueue.IsBlackArr[wkInd];
}
WillEnqueue.Log = new List<bool[]>(Dequeued.Log) { WillEnqueue.IsBlackArr };
que.Enqueue(WillEnqueue);
}
}
}
//クリア判定
static bool IsClear(int pUB, bool[] pIsBlackArr)
{
bool[] Answer1 = new bool[pUB + 1];
bool[] Answer2 = new bool[pUB + 1];
for (int I = 0; I <= pUB; I++) {
//偶数が黒で、奇数が白
Answer1[I] = (I % 2 == 0);
//偶数が白で、奇数が黒
Answer2[I] = (I % 2 == 1);
}
return pIsBlackArr.SequenceEqual(Answer1) || pIsBlackArr.SequenceEqual(Answer2);
}
}
実行結果
n=3での解を発見
0手目
■■■□□□
1手目
■□□■□□
2手目
■□■□■□
n=8での解を発見
0手目
■■■■■■■■□□□□□□□□
1手目
□□□■■■■■□□□□□□□□
2手目
□■■□■■■■□□□□□□□□
3手目
□■□■□■■■□□□□□□□□
4手目
□■□■□■□□■□□□□□□□
5手目
□■□■□■□■□■□□□□□□
6手目
□■□■□■□■□■□■■■□□
7手目
□■□■□■□■□■□■□□■□
8手目
□■□■□■□■□■□■□■□■
解説
最短の回数を求めればいいので、幅優先探索を使ってます。