华夫饼堆叠算法需要改进

时间:2014-07-01 17:28:15

标签: java algorithm puzzle

我正在研究一个名为Waffle Stacking的问题。我知道一个问题已经存在,但是帖子需要知道从哪里开始,但我已经完成了大部分工作。这个问题可以在这里看到:http://www.hpcodewars.org/past/cw16/problems/Prob20--WaffleStacking.pdf

我的算法计算字符串" 12345"的120个排列(5!)。然后我逐行放置并确保它们与侧面线索匹配。然后我检查到目前为止是否匹配顶端。 (这意味着我浏览了我目前拥有的磁贴,找到了最高的堆栈,然后查找未使用的堆栈并检查它们是否高于当前最高堆栈,然后我可以看到是否使用了未匹配的堆栈,它们将匹配线索)。使用这个例子,我的算法非常有缺陷。它只产生4行,只有一行是正确的。我相信这是由于检查专栏。通过检查顶部和底部来确认任何帮助。

package HP2013;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;

public class WaffleStacking
{

public static String t[];
public static String l[];
public static String r[];
public static String b[];

public static void getInput()
{
    try{
        Scanner keyb = new Scanner(new File("src/HP2013/WaffleStacking.dat"));

        t = keyb.nextLine().split(" ");
        l = new String[5];
        r = new String[5];
        for (int i = 0; i < 5; i++)
        {
            String a[] = keyb.nextLine().split(" ");
            l[i] = a[0];
            r[i] = a[1];
        }
        b = keyb.nextLine().split(" ");
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

public static ArrayList<String> perms = new ArrayList<String>();

public static void getPerms(String s)
{
    getPerms("", s);
}

public static void getPerms(String pfx, String s)
{
    int n = s.length();

    if (n == 0)
        perms.add(pfx);
    else
    {
        for (int i = 0; i < s.length(); i++)
            getPerms(pfx + s.charAt(i) + "", s.substring(0, i) + s.substring(i + 1));
    }
}

public static void solve()
{
    int mat[][] = new int[5][5];

    for (int r = 0; r < 5; r++)
    {
        String row = "";

        for (int p = 0; p < perms.size(); p++)
        {
            if (goodRow(perms.get(p), r))
            {
                row = perms.get(p);
                for (int c = 0; c < row.length(); c++)
                    mat[r][c] = Integer.valueOf(row.charAt(c) + "");

                if (uniqueCol(mat, r + 1) && goodCol(mat, r + 1))
                    break;
                else
                {
                    mat[r] = new int[] {0, 0, 0, 0, 0}.clone();
                }
            }
        }
    }

    for (int m[] : mat)
        System.out.println(Arrays.toString(m));
}

public static boolean uniqueCol(int mat[][], int rStop)
{
    for (int c = 0; c < mat.length; c++)
    {
        ArrayList<Integer> col = new ArrayList<Integer>();
        for (int r = 0; r < rStop; r++)
            col.add(mat[r][c]);
        Collections.sort(col);
        for (int i = 0; i < col.size() - 1; i++)
            if (col.get(i) == col.get(i + 1))
                return false;
    }
    return true;
}

public static boolean goodRow(String row, int index)
{
    int left = 0;
    int max = -1;
    for (int i = 0; i < row.length(); i++)
    {
        int stack = Integer.valueOf(row.charAt(i) + "");
        if (stack > max)
        {
            left++;
            max = stack;
        }
    }

    int right = 0;
    max = -1;
    for (int i = row.length() - 1; i >= 0; i--)
    {
        int stack = Integer.valueOf(row.charAt(i) + "");
        if (stack > max)
        {
            right++;
            max = stack;
        }
    }

    if (left == Integer.valueOf(l[index]) && right == Integer.valueOf(r[index]))
        return true;
    return false;
}

public static boolean goodCol(int mat[][], int rStop)
{
    return checkTop(mat, rStop);
}

public static boolean checkTop(int mat[][], int rStop)
{
    for (int c = 0; c < 5; c++)
    {
        int left = Integer.valueOf(t[c] + "");
        int max = -1;
        String used = "";
        for (int r = 0; r < rStop; r++)
        {
            int stack = mat[r][c];
            used += stack;
            if (stack > max)
            {
                max = stack;
                left--;
            }
        }
        ArrayList<Integer> leftovers = new ArrayList<Integer>();
        for (int n = 1; n <= 5; n++)
        {
            if (!used.contains(n + ""))
                leftovers.add(n);
        }
        for (int j = 0; j < leftovers.size(); j++)
        {
            if (leftovers.get(j) > max)
            {
                max = leftovers.get(j);
                left--;
            }
        }
        if (left > 0)
            return false;
    }
    return true;
}

public static void main(String args[])
{
    getInput();
    getPerms("12345");
    solve();
}

}

输入: 2 2 3 2 1

4 1

1 4

3 2

2 2

3 2

3 2 1 3 4

输出: [1,3,2,4,5]

[5,1,4,3,2]

[2,4,1,5,3]

[3,2,5,1,4]

[0,0,0,0,0]

2 个答案:

答案 0 :(得分:0)

所以,当你找到一个好的答案时,我看到的第一个问题是无法跳出来。在他们找到正确的答案并展开到你因为你的条款不匹配而导致你失去最后一行之后,你的循环可能还在继续。

答案 1 :(得分:0)

底部检查不是问题,我推翻了它;它应该与顶部检查非常相似。求解方法非常错误,我切换到递归解决方案,最终解决了问题。这样我可以尝试多种有效行的可能性,同时保持唯一列,然后检查列是否也有效。如果他们不是,我可以继续尝试不同的可能性。