有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java UVa在线法官第100次(3n+1)uDebug显示所有答案都是正确的,但都是错误的

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

下面列出了我为解决这个问题所做的工作。在过去的几个小时里,我一直在做这件事,我真的想把它全部扔掉,但这会让我非常烦恼,所以这是我最后的希望

我做过的事情:

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

我不太确定的事情:

  • 我想我读到UVa不希望它的类是public。所以我把我的名字改为class Main,而不是通常的public class Main。另一个地方的人提到应该是后者。不知道在线法官喜欢哪一个
  • 输入。我用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) 个答案

  1. # 1 楼答案

    还没有发现你的错误,但是有一些事情可能会让你更容易发现

    首先:

    int变为2^31,因此在main方法中声明i为long是不必要的。它还在问题规范中声明,任何操作都不会溢出int,不是吗?去掉无关的long(和(int)类型转换将更容易理解

    第二:

    使用C++ 1的递归调用比++C或C++之前更容易。这些都有副作用,这让你更难理解你在做什么(因为如果你增加c,一定有原因,对吧?)你写的东西在技术上是正确的,但它太过单一,以至于会分散你的注意力

    第三:

    那么,是我遗漏了什么,还是你从来没有在记忆功能中设置列表中的任何值?如果我不是瞎子(这是一种可能性),这肯定会阻止它按原样通过。等等,不,绝对是瞎的——你是在循环中做的。对于这种函数,我希望它能改变函数中的列表。当你为i=1调用它时,你在计算i=4(3*1+1)——你也可以保存它