using System; using System.Collections.Generic; class Program { const int LimitN = 40; static int[] HeihousuuArr; //平方数を列挙 static void DeriveHeihousuuArr() { var HeihousuuList = new List<int>(); for (int I = 0; I * I <= LimitN * 2; I++) { HeihousuuList.Add(I * I); } HeihousuuArr = HeihousuuList.ToArray(); } static void Main() { DeriveHeihousuuArr(); for (int LoopN = 2; LoopN <= LimitN; LoopN++) { Console.WriteLine("N={0}で解を調査します。", LoopN); if (HasAnswer(LoopN)) break; } } struct JyoutaiDef { internal int CurrP; internal int[] NumArr; } //Nを引数として、解が存在するかを返す static bool HasAnswer(int pN) { int UB = pN - 1; var stk = new Stack<JyoutaiDef>(); JyoutaiDef WillPush; WillPush.CurrP = 1; WillPush.NumArr = new int[UB + 1]; WillPush.NumArr[0] = 1; //1個目のイチゴは固定で1個とする stk.Push(WillPush); while (stk.Count > 0) { JyoutaiDef Popped = stk.Pop(); //クリア判定 if (Popped.CurrP > UB) { Console.WriteLine("解を発見。"); for (int I = 0; I <= UB; I++) { Console.Write("{0,2},", Popped.NumArr[I]); if (I % 10 == 9 || I == UB) Console.WriteLine(); } return true; } WillPush.CurrP = Popped.CurrP + 1; for (int I = 1; I <= pN; I++) { int wkInd = Array.IndexOf(Popped.NumArr, I, 0, Popped.CurrP); if (wkInd >= 0) continue; //Prevの要素との和が平方数であること int wkSum1 = I + Popped.NumArr[Popped.CurrP - 1]; if (Array.BinarySearch(HeihousuuArr, wkSum1) < 0) continue; //Nextの要素との和が平方数であること if (Popped.CurrP == UB) { int wkSum2 = I + Popped.NumArr[0]; if (Array.BinarySearch(HeihousuuArr, wkSum2) < 0) continue; } WillPush.NumArr = (int[])Popped.NumArr.Clone(); WillPush.NumArr[Popped.CurrP] = I; stk.Push(WillPush); } } return false; } }
省略 N=30で解を調査します。 N=31で解を調査します。 N=32で解を調査します。 解を発見。 1,15,10,26,23, 2,14,22,27, 9, 16,20,29, 7,18,31, 5,11,25,24, 12,13, 3, 6,30,19,17,32, 4,21, 28, 8,
深さ優先探索でイチゴの数を順に求めてます。