USACO:任务检查员挑战

时间:2011-05-04 23:47:28

标签: java

- UPDATE -

我通过在C ++中重写并提交来解决这个问题。不完全是最负盛名的方式,但确实有效!

- END UPDATE -

我正在做USACO检查器问题,天哪,我快要拔掉头发了!我有一个解决方案,但最后一个测试用例(n = 13)约为0.3秒。下面的程序是否有任何方式可以更快地运行?

如果有什么我可以添加帮助,请告诉我!

编辑:程序必须运行< 1秒w / compilation。

import java.io.*;
class checker
{
    static int n;
    static boolean ifCol[];
    static boolean rDiag[] = new boolean [26];
    static boolean lDiag[] = new boolean [26];
    static int col[];
    static int print;
    static int counter;
    static PrintWriter out;
    private static void search (int row)
    {
        if (row == n)
        {
            if (print < 3)
            {
                out.print (col [0] + 1);
                for (int i = 1 ; i < n ; i++)
                    out.print (" " + (col [i] + 1));
                out.println ();
                print++;
            }
            counter++;
            return;
        }
        for (int i = 0 ; i < n ; i++)
        {
            if (!ifCol [i] && !rDiag [i - row + 13] && !lDiag [i + row])
            {
                ifCol [i] = rDiag [i - row + 13] = lDiag [i + row] = true;
                col [row] = i;
                search (row + 1);
                ifCol [i] = rDiag [i - row + 13] = lDiag [i + row] = false;
            }

        }
        return;
    }


    public static void main (String[] args) throws IOException
    {
        //long start = System.currentTimeMillis ();
        BufferedReader in = new BufferedReader (new FileReader ("checker.in"));
        out = new PrintWriter (new BufferedWriter (new FileWriter ("checker.out")));
        n = Integer.parseInt (in.readLine ());
        col = new int [n];
        ifCol = new boolean [n];
        search (0);
        out.println (counter);
        //out.println (System.currentTimeMillis()-start);
        out.close ();
        System.exit (0);
    }
}

问题陈述: 检查员挑战

检查下面的6x6棋盘并注意六个棋子被安排在棋盘上,这样每行和每一列中只有一个,并且在任何对角线上都不会有一个。 (对角线从东南向西北,西南向东北延伸,包括所有对角线,而不仅仅是主要的对角线。)

      Column
1   2   3   4   5   6

1 | | O | | | | |


2 | | | | O | | |


3 | | | | | | O |


4 | O | | | | | |


5 | | | O | | | |


6 | | | | | O | |


上面显示的解决方案由序列2 4 6 1 3 5描述,它给出了每行从1到6的检查器的列位置:

行1 2 3 4 5 6 第2栏4 4 1 3 5 这是检查挑战的一种解决方案。编写一个程序,找到Checker Challenge的所有独特解决方案序列(N值不断增长)。使用上述列符号打印解决方案。按数字顺序打印前三个解决方案,好像检查器位置形成一个大数字的数字,然后是一个包含解决方案总数的行。

特别说明:较大的N值要求您的程序特别有效。不要预先计算价值并将其打印出来(甚至找到它的公式);那是作弊。处理您的程序,直到它可以正确解决问题。如果您坚持作弊,您登录USACO培训页面将被删除,您将被取消参加所有USACO比赛的资格。你已经被警告了。

时间限制:1秒CPU

计划名称:检查程序

输入格式

包含单个整数N(6 <= N <= 13)的单行,其是N×N棋盘的尺寸。 SAMPLE INPUT(文件检查器.in)

6

输出格式

前三行显示找到的前三个解决方案,显示为N个数字,它们之间有一个空格。第四行显示找到的解决方案总数。 SAMPLE OUTPUT(文件检查器.out)

2 4 6 1 3 5

3 6 2 5 1 4

4 1 5 2 6 3

4

2 个答案:

答案 0 :(得分:2)

用C代替Java。

我和你的情况相同,在解决问题大约一个小时之后,我决定换语言。

我甚至没有改变我的算法,它的运行速度提高了10倍。

(在您完成挑战之后,您可以阅读分析并了解您可以进行的其他优化。)

我知道这是一个非常晚的回复你很久以前就忘记了这个问题....... :)

答案 1 :(得分:0)

我观察到问题减少为枚举整数1到N的所有排列,除了有序序列1到N和N到1(代表对角线)。算法上有很多文本可以为你生成排列。