In this blog post we will have a look at fast I/O methods for competitive programming in C++, Java and Python.
Problem
In competitive programming it is important to read the input as fast as possible so we don’t lose valuable time. We can test our input and output methods on the problem INTEST – Enormous Input Test on SPOJ. Before you keep on reading I encourage you to solve the problem first.
1. Solution in C++ 4.9.2
– Bad way:
The code below uses cin and cout. The solution gets accepted with a runtime of 2.17 seconds.
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, k, t;
int cnt = 0;
cin >> n >> k;
for(int i=0; i<n; i++){
cin >> t;
if(t % k == 0) cnt++;
}
cout << cnt << "\n";
return 0;
}
+ Good way:
However, we can do better and reduce the runtime a lot by adding two lines. The program below gets accepted with a runtime of 0.41 seconds.
#include <bits/stdc++.h>
using namespace std;
int main(){
// add the two lines below
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, k, t;
int cnt = 0;
cin >> n >> k;
for(int i=0; i<n; i++){
cin >> t;
if(t % k == 0) cnt++;
}
cout << cnt << "\n";
return 0;
}
2. Solution in Java 8
– Bad way:
The code below uses the slow Scanner class and gets a time limit exceeded verdict.
import java.io.*;
import java.util.*;
// testing slow Scanner
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int cnt = 0;
int n = sc.nextInt();
int k = sc.nextInt();
int t;
for(int i=0; i<n; i++){
t = sc.nextInt();
if(t % k == 0) cnt++;
}
System.out.println(cnt);
}
}
+ Good way:
The code below uses the custom class MyScanner which uses a BufferedReader and a PrintWriter. It gets accepted with a runtime of 1.23 seconds.
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) {
MyScanner sc = new MyScanner();
out = new PrintWriter(new BufferedOutputStream(System.out), true);
// Start writing your solution here. -------------------------------------
int cnt = 0;
int n = sc.nextInt();
int k = sc.nextInt();
int t;
for(int i=0; i<n; i++){
t = sc.nextInt();
if(t % k == 0) cnt++;
}
out.println(cnt);
/*
int n = sc.nextInt(); // read input as integer
long k = sc.nextLong(); // read input as long
double d = sc.nextDouble(); // read input as double
String str = sc.next(); // read input as String
String s = sc.nextLine(); // read whole line as String
int result = 3*n;
out.println(result); // print via PrintWriter
*/
// Stop writing your solution here. -------------------------------------
out.close();
}
//-----------PrintWriter for faster output---------------------------------
public static PrintWriter out;
//-----------MyScanner class for faster input----------
public static class MyScanner {
BufferedReader br;
StringTokenizer st;
public MyScanner() {
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() { return Integer.parseInt(next()); }
long nextLong() { return Long.parseLong(next()); }
double nextDouble() { return Double.parseDouble(next()); }
String nextLine(){
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
//--------------------------------------------------------
}
See also this blog post for references.
3. Solution in Python 3.4
– Bad way:
The program below uses input and print and gets the verdict time limit exceeded.
def main():
n, k = [int(c) for c in input().split()]
cnt = 0
for _ in range(n):
t = int(input())
if t % k == 0:
cnt += 1
print(cnt)
if __name__ == "__main__":
main()
+ Good way:
Instead of input and print we should use stdin.readline() and stdout.write(). The program below gets accepted with a runtime of 2.36 seconds.
from sys import stdin, stdout
def main():
n, k = [int(c) for c in input().split()]
cnt = 0
for _ in range(n):
t = int(stdin.readline())
if t % k == 0:
cnt += 1
stdout.write(str(cnt))
if __name__ == "__main__":
main()
Note that you have to pass a string to stdout.write(), see also this blog post.
++ Better way:
We can read the whole input at once and load it into a list. The code below gets accepted with a runtime of 1.70 seconds. See also How to get REALLY fast Python over a simple loop.
def main():
from sys import stdin, stdout
n, k = stdin.readline().split()
n = int(n)
k = int(k)
cnt = 0
lines = stdin.readlines()
for line in lines:
if int(line) % k == 0:
cnt += 1
stdout.write(str(cnt))
if __name__ == "__main__":
main()
Reblogged this on Dinesh Ram Kali..
What about C? I’ve always been puzzled by how getchar_unlocked() works & how it should be used.