现在我们获得了一个区域的可能填充,那么得到答案的最简单的方法就是一个个试。我的策略是先从1(蓝色)开始,1不行就用2(绿色),再不行就3(黄色)或4(红色)。
通过函数穷举判断PossibleSolutionThis的第一个可用颜色,并保存到FinalSolutionThis这个nbt中。这个nbt即表示当前这个区域正在使用的填色。同时,使用穷举函数将PossibleSolutionThis和FinalSolutionThis保存到PossibleSolution和FinalSolution下对应编号的nbt内。这样FinalSolution里就保存了所有区域正在使用的填色,而PossibleSolution里保存了所有区域的可用填色。结果如下图所示:
" class="BDE_Image" onload="EditorUI.resizeImage(this, 560)" unselectable="on"/>
这里的各个NBT的作用:
PossibleSolution 用于保存所有区域的填色可能
PossibleSolutionThis 用于保存当前正在分析的区域的填色可能
FinalSolution 用于保存所有区域的正在使用的填色
FinalSolutionThis 用于保存当前正在分析的区域正在使用的填色
除此之外,PossibleSolution也用于出错时能够方便地进行修正,而FinalSolution则用于生成最终解
回到刚刚抛出的一个问题。如果在分析可用填色时发现无可用填色,说明附近的一个已有填色的区域的填色出错了。由于不知道具体是哪个区域出错,还是只能一个个试。我的选择是为附近的编号比当前编号小的编号最大的区域重新填色。
首先通过穷举函数获取附近的编号最大但又比当前区域编号小的区域,保存至NearestId中,并转移至记分板。通过穷举函数获取该编号的区域记录下的PossibleSolution和FinalSolution,分别保存至PossibleSolutionThis和FinalSolutionThis中。再通过穷举在PossibleSolutionThis中将FinalSolutionThis的解标记为不可用(0b)。随后复制好其他信息,重新分析PossibleSolutionThis中是否有可用解。
重新分析的过程中,PossibleSolutionThis是直接从之前的记录中获取的,因此不再需要初始化(甚至因为做过标记,而不能进行初始化)。
这里讨论一下之前留下的一个问题。如果区域x填充后,区域y被认定无解,而区域x又恰好是编号比y小的区域中编号最大的一个,那么重新填充的x是否要依据其他有填充而编号又比x大的区域进行填充?(比如,区域4和区域5,6相邻,区域5,6互相不相邻,而区域6被认定无解,此时区域4的填充是否需要考虑区域5的填充)
我的观点是,此处区域4的填充不应参考区域5的填充。因为首先区域5的填充是参考了区域4的,如果区域4有变,那么区域5的填充也会有变化。那么,在之前情形下得到的结论在这种情形下不再适用,所以不应直接使用。因此,区域4的可用填充可以直接从记录中获取,而区域5的填充则需要重新初始化,并重新讨论分析。