UVa Online Judge 100th(3n + 1)uDebug显示一切正确但错误的答案

时间:2016-03-18 00:51:42

标签: java

这是我的第一次UVa提交,所以我遇到了一些问题。到目前为止,我花费时间的最大障碍可能是正确地获取所有格式(我知道,不应该太难,但我不知道在这种情况下实际意味着什么,我一直得到运行时错误)。我终于遇到了运行时错误,但我仍然得到“错误答案。”

下面列出了我为此问题所做的事情。我在过去几个小时里一直在研究这个问题,老实说我只想完全放弃它,但这会让我很烦,所以这是我最后的希望。

我做过的事情:

  • 考虑int溢出,因此在适用的地方更改为long
  • 通过记忆计算时间得到了整个列表(1-1000000)
  • 提交给uDebug。关键输入和随机输入都显示匹配输出。
  • 提交给UVa在线评委,并以0.13~0.15运行时获得“错误答案”。

我不太确定的事情:

  • 我想我读过UVa不希望它的类是public。所以我把class Main留给了我,而不是通常的public class Main。来自另一个地方的人提到它应该是后者。不确定哪位UVa在线评委喜欢。
  • 输入。我使用了BufferedReader(new InputStreaReader (System.in))。也不确定UVa在线评判是否喜欢这个。
  • 我认为我的算法是正确的,但由于“错误的答案”,我不太确定。如果我的代码难以阅读,我将尝试描述我在代码之后所做的事情。

这是我的代码:

class Main {

    public static int mainMethod(long i, int c, List<Integer> l) {
        if (i==1)
            return ++c;
        else if (i%2==0) {
            if (i<1000000&&l.get((int)i)!=null)
                return l.get((int)i)+c;
            else {
                c++;
                return mainMethod(i/2, c, l);
            }
        }
        else {
            if (i<1000000&&l.get((int)i)!=null)
                return l.get((int)i)+c;
            else {
                c++;
                return mainMethod(i*3+1, c, l);
            }
        }
    }

    public static int countMax(int x, int y, List<Integer> l) {
        int max=0;
        if (x>y) {
            int temp = x;
            x= y;
            y = temp;

        }
        for (int i=x; i<=y; i++) {
            if (l.get(i)>max)
                max = l.get(i);
        }
        return max;
    }

    public static void main(String[] args) {

        List<Integer> fixed = Arrays.asList(new Integer[1000000]);

        for (long i=1; i<1000000; i++) {
            fixed.set((int)i, mainMethod(i,0,fixed));
        }
        String s;
        try {

            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            while ((s = br.readLine())!=null) {
                int x = -1;
                int y = -1;
                for (String split : s.split("\\s+")) {
                    if (!split.equals("\\s+") && x==-1) {
                        x = Integer.parseInt(split);
                    } else if (!split.equals("\\s+") && x!=-1) {
                        y = Integer.parseInt(split);
                    }
                }
                if (x!=-1&&y!=-1)
                    System.out.println(Integer.toString(x) + " " + Integer.toString(y) + " " + Integer.toString(countMax(x,y,fixed)));
            }
        } catch (IOException e) {

        } catch (NumberFormatException e) {

        }


    }

}

我为方法和变量的通用名称道歉。 mainMethod处理记忆并创建初始列表。 countMax处理问题的输入(15 20)并使用列表查找最大长度。 main方法中的for循环处理潜在的空行和太多空格。

所以我的(如果不是那么明显)问题是,我的代码出了什么问题?同样,这在uDebug的随机输入和关键输入上完全正常。然而,出于某种原因,UVa在线评委表示这是错误的。我对它的位置一无所知。我是学生,所以我还在学习。谢谢!

1 个答案:

答案 0 :(得分:0)

Haven尚未发现您的错误,但有些事情可能会让您更容易被发现。

首先关闭:

int转到2 ^ 31,因此在mainMethod中声明为long是不必要的。它还在问题规范中说明没有操作会溢出int,不是吗?摆脱无关的长篇(和(int)演员表)会让你更容易理解。

第二:

使用c + 1而不是++ c进行递归调用或在c ++之前执行c ++可能更清楚。那些有副作用,这使得你更难以遵循你所做的事情(因为如果你增加c,必须有一个理由,对吧?)你写的是技术上正确的,但它足够单一,分散注意力。

第三:

那么,我是否遗漏了某些内容,或者您​​是否实际上没有在记忆功能中设置列表中的任何值?如果我不盲目(这是一种可能性)肯定会阻止它原样传递。等等,不,绝对是盲目的 - 你在调用它的循环中做它。有了这种功能,我希望它能在函数中改变List。当你为i = 1调用它时,你计算i = 4(3 * 1 + 1) - 你也可以保存它。