ACPC 2025 - Language-Specific Tips & Tricks
After correctness, the main metric of success in competitive programming is runtime duration. Every problem has a static amount of time that all solutions have to run within. However, some languages are faster than others. In order to level the playing field and allow for greater language support in this competition, we are including this document which we hope will provide very simple tips on how to get free performance gains in this contest as well as provide some warnings about pitfalls that might make your solution timeout.
All problems were tested and designed around C++ and Python. Each problem has been proven to work in these languages, even without some of the optimizations below. That being said, depending on your implementation, there are situations where the tips here can mean the difference between a successful submission and a failed one, so we strongly recommend you consider them in your solutions.
For all typed languages, use 64-bit primitives wherever possible. This will ensure you do not get unexpected overflow issues in your solutions.
The easiest trick to get IO performance out of your C++ application is to include the following macro at the start of your solution:
#define SPEED \ std::ios::sync_with_stdio(false); \ |
This prevents some default behavior with std::cin where it will force std::cout to flush before reading input. Since competitive programming often involves reading large amounts of data, performing some algorithm on this data and then producing output – often back and forth many times – this tying behavior causes unnecessary overhead that can greatly affect performance on input-heavy problems.
Codeforces includes a few options for compilers/runtimes when submitting your Python solution. We generally recommend using PyPy 3.10 as such:
Python IO is often invoked through the input() and print() functions. However, you can get a large performance increase by using sys.stdin and sys.stdout as such:
import sys |
These directly access the C standard input and output streams with very little overhead, unlike the standard Python IO functions. However, each of the problems on ACPC 2025 are doable using input() and print(), without these optimizations.
Python strings are immutable. As such, if you want to build a string out of smaller results – such as converting a list to a string – then you may be doing a large number of costly copying operations without noticing.
The easiest workaround to this is to build a list of your results instead, then converting it into a string all at once with the join() function. This will work for any type of list whether its a list of characters, a list of strings, or a list of integers like in this example:
import sys |
Here, we do a list comprehension to convert each of our integers to a string (unnecessary if list elements are already strings) and then we call join() on a string containing one whitespace character – this acts as our delimiter. The result is one string where each value is separated by one whitespace character.
Python has a default recursion limit of 1000 (103). This is able to be increased with vanilla Python, but it cannot be changed in Codeforces’ PyPy runtime. Once this limit is exceeded, Codeforces reports a runtime error - if your recursive code outputs a runtime error, first ensure that it is not going over the recursion limit.
There are two main workarounds for the recursion limit.
These workarounds are discussed more in-depth in the ACPC Python Guide repo.
For input, a combination of BufferedReader and StringTokenizer is recommended. Here’s a simple static class that utilizes these, where the FastScanner.next() function will return the next space-separated string from the input:
static class FastScanner { new BufferedReader(new InputStreamReader(System.in)); |
However, all problems in ACPC 2025 are solvable using standard Scanner functions, without this optimization.
For output, it is recommended to combine output into a single string before printing. As is described in the next section, StringBuilder should be used for all string generation:
// Print space-separated elements of integer array on a line |
Java strings are immutable. As such, if you want to build a string out of smaller results – such as converting an array to a string – then you may be doing a large number of costly copying operations without noticing.
Thankfully, Java includes a class for building strings, conveniently named StringBuilder. This has an append() function that will accept any primitive data type, string, or object with a toString() definition. An example of using StringBuilder is included in the output portion of the IO section.