九宫格游戏

    技术2022-05-20  38

    有一个类九宫格(如下),灰色三角形一次编号0-9,选中其中一个作为空格,其余各编号三角形中可能被填充红、蓝、绿、黄四种颜色,

    求从任意一个起始布局(init)开始,变换至任意的目标布局(goal),如果成功,返回0;如果失败,则求至少需要替换多少个格子的填充色,然后方能成功,返回需替换的格子数。

     

    举例:init="BG*YRGRRYR",goal="BGGY*YRRRR",布局字符串第i位表示第i个格中颜色(RGBY依次是颜色,*为空格),经由如下变换序列,由init可以成功变换为goal,所以无需改变任何一格的颜色,返回0

    对此题的第一反应是觉得题型像深度遍历求可能解一类,然后对比所有可能序列与目标序列的差异并取最小值,但是实际深度遍历并不可行,因为无法确定遍历的结束边界(即使空格到了目标格也还可以继续,因为可此导出其他序列),所以否定深度遍历。

     

    再回头看看宫格,想想其中奥妙,发现有一些规律:

    1)任意连着空格的两个格子,颜色可一个互换,其他格子颜色保持不变。比如假设空格是7,则6和8可以在保持3和4不变情况下互换位置,变换过程:7沿着6->3->4->8走一圈再回归原位位,于是6到达8的位置,好比除7外3486 时针移动了一格,然后固定6,再类似的 时针转动348,于是8到达6的原来位置,3、4和7都不动,6和8互换完成。

    2)基于第一个规律,空格可以移动至某个位置,互换某两个相邻的格子,然后再沿原路返回,于是可以达到互换任意两个空格的效果,与空格的实际位置并无关系。

     

    有了如上规律,可以得出思路,首先将空格移到目标格,然后按需要互换任意空格的颜色,使其与目标布局尽量匹配,如果不行,则替换颜色,所以实际解很简单,就等价于求init和goal相异颜色的个数除2。

     

    public int getMinimumCost(String init, String goal) { int IR=0, IG=1, IB=2, IY=3; int[] stacks = new int[4]; for(int i=0; i<init.length(); i++) { switch(init.charAt(i)) { case 'R': stacks[IR]++; break; case 'G': stacks[IG]++; break; case 'B': stacks[IB]++; break; case 'Y': stacks[IY]++; break; } switch(goal.charAt(i)) { case 'R': stacks[IR]--; break; case 'G': stacks[IG]--; break; case 'B': stacks[IB]--; break; case 'Y': stacks[IY]--; break; } } int diff=0; for(int i=0; i<stacks.length; i++) { diff += Math.abs(stacks[i]); } return (diff/2); }

     

     

     


    最新回复(0)