Tuesday, 20 January 2015

SPOJ - Enormous Input and Enormous Output - Solution in Java

Today we will discuss about how to go about solving
ENORMOUS INPUT and ENORMOUS INPUT and OUTPUT problem.

The purpose of the first problem is read input as fast as possible. To be precise, we need to read 2.5MB/sec.

The second problem is to read input as fast as possible as well as output the results faster.


Problem 1 : Approach

Using BufferedReader to read the inputs.

The following solution contains nothing complicated to explain. 

a) We have used try with resources of Java 7 which takes care of closing the resource even in case of an exception. This is one of the best practices in Java 7.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 

class EnormousInput
{
    public static void main(String[] args) throws IOException
    {
        int totalNumsDivisibleByK = 0;
      
        try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))
        {
            int[] nAndK = getNandK(br);
            int n = nAndK[0];
            int k = nAndK[1];
            int[] allInputs = getAllInputs(br, n);
            totalNumsDivisibleByK = findTotalNumsDivisibleByK(allInputs, k);
        }
      
        System.out.print(totalNumsDivisibleByK);
    }

    private static int[] getAllInputs(BufferedReader br, int n) throws IOException
    {
        int[] allIntegers = new int[n];
        for (int i = 0; i < allIntegers.length; i++)
        {
            allIntegers[i] = Integer.parseInt(br.readLine());
        }
      
        return allIntegers;
    }

    private static int findTotalNumsDivisibleByK(int[] allInputs, int k) throws IOException
    {
        int totalNumsDivisibleByK = 0;
      
        for (int i = 0; i < allInputs.length; i++)
        {
            if (allInputs[i] % k == 0)
            {
                totalNumsDivisibleByK++;
            }
        }
        return totalNumsDivisibleByK;
    }

    private static int[] getNandK(BufferedReader br) throws IOException
    {
        int[] aNandK = new int[2];
      
        String firstLine = br.readLine();
        String[] tokens = firstLine.split("\\s+");
        int n = Integer.parseInt(tokens[0]);
        int k = Integer.parseInt(tokens[1]);
        aNandK[0] = n;
        aNandK[1] = k;
      
        return aNandK;
    }
}


This solution takes around 0.90 secs and gets accepted.


Problem 2 : Approach

Here also we use BufferedReader to read the inputs. For printing outputs we need to have a similar mechanism so that we don't spend much time in the I/O. We can use BufferedWriter. I have tried with StringBuilder to accumulate the outputs and print the final output once. 

Each outputs must be seperated by new line so I have made use of System.lineSeparator() which is available in Java 7.


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 

class EnormousInputAndOutput
{
    public static void main(String[] args) throws IOException
    {
        try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))
        {
            int n = Integer.parseInt(br.readLine());
           
            String output = getMultipliedValueOfEachInput(br, n);
           
            System.out.print(output);
        }
    }

    private static String getMultipliedValueOfEachInput(BufferedReader br, int n) throws IOException
    {
        StringBuilder sb = new StringBuilder();
       
        for (int i = 1; i <= n; i++)
        {
            String[] nums = br.readLine().split("\\s+");
            int num1 = Integer.parseInt(nums[0]);
            int num2 = Integer.parseInt(nums[1]);
           
            int output = num1 * num2;
           
            sb.append(output);
            sb.append(System.lineSeparator());
        }
       
        return sb.toString();
    }
}


The solution takes around 1.30 secs and gets accepted.

No comments:

Post a Comment