Java on the SOI Grader

Written by Johannes Kapfhammer. Translated by Johannes Kapfhammer.

General Remarks

Java is supported for the second round and finals of SOI, and also at IOI. We guarantee that all tasks from the second round can be solved for 100 points in Java. While we don’t double-check that for the finals (there we only write our solutions in C++), we strongly assume that Java will be able to get 100 points.

To run Java on the SOI grader, there’s a few points to consider:

  • We run Java 7 on OpenJDK (Java 1.7.0_231, OpenJDK Runtime Environment (IcedTea 2.6.19), OpenJDK 64-Bit Server VM).
  • You need to submit a single file to be compiled as “submission.java”. Therefore the outermost class has to be called “submission” (note the lowercase letters).
  • Since Java can be a bit slower and more memory-hungry than C++, you will have twice the time and memory available. If, for example, it says on some task “Time limit: 1000ms, memory limit: 256MiB”, then Java will have a time limit of 2000ms and memory limit of 512MiB.
  • Input with the Scanner class is quite slow, even with the increased time limit it won’t pass. So we recommend using BufferedReader and StringTokenizer instead (see template below).
  • If possible, use built-in arrays. They are by far the fastest way to store lists. For dynamic arrays (e.g. for adjacency lists in graphs), you can use ArrayList<> (stay away from LinkedList<>, ArrayList<> is better in pretty much all situations).

SOI Java Template

ExpandCopy
import java.io.*;
import java.util.*;

class Task {
    public void solve(InputReader in, PrintWriter out) {
        int n = in.nextInt();
        out.println(n);
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }
}

public class submission {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task();
        solver.solve(in, out);
        out.close();
    }
}

Although you are free to code however you like, we recommend using the template above when solving tasks in Java.

For faster I/O, this uses BufferedReader and StringTokenizer and then manually converts strings to ints. For easier usage, it wraps this in a class InputReader that behaves like the Scanner class and contains the two methods next (for reading a string), nextInt (for reading an int), nextLong (for reading a long).

When using this template, all you need to implement is the method solve in the class Task. Note that all classes except submission are package-private.

Feel free to make use of member variables and methods inside the class Task. The following is a perfectly valid solution for the task addition:

class Task {
    long a;
    long b;

    public void solve(InputReader in, PrintWriter out) {
        a = in.nextLong();
        b = in.nextLong();
        out.println(add());
    }

    long add() {
        return a + b;
    }
}