Timed Out and NZEC on CodeChef Problem NUKES - java

While trying out the problem "Nuclear Reactors" , i'm getting the results on my computer ,but in CodeChef there is a timelimit of 0.2 secs and while submitting my answer i'm getting a TLE(time limit exceeded) error and in one test i'm getting wrong answer.
I don't have a clue what is causing this.
Any hints would be helpful.
Link :https://www.codechef.com/problems/NUKES
My code :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args) {
FastReader fr = new FastReader();
// I/P
int a = fr.nextInt();
int n = fr.nextInt();
int k = fr.nextInt();
// ARRAY TO STORE RESULT
int react[] = new int[k];
// ARRAY OF ZERO AND ONES
int temp_one[]=new int[k];
int temp_zero[]=new int[k];
for (int i = 0; i < k; i++){
react[i] = 0;
temp_zero[i]=react[i];
temp_one[i]=1;
}
while (a != 0) { // TO REPEAT TILL ALL (A) ARE USED
int j = 0;
while(react[j]>=n){ // CHECK(value in K>=A)
react[j] = 0;
j++;
}
react[j]++;
if(Arrays.equals(react,temp_one)){ // CHECK(all K are filled)
react=temp_zero;
}
a--;
}
for(int i=0;i<k;i++){
System.out.print(react[i]+" ");
}
}
//////////////////// FAST IO //////////////////////
static class FastReader{
BufferedReader br;
StringTokenizer st;
public FastReader() {
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());
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
Results given by CodeChef

This code should work for your algorithm.
int[] ret = new int[k];
for(int i = (int)(Math.log(a)/Math.log(n+1)); i >= 0; i--) {
int val = (int)(a/Math.pow(n+1,i));
a -= val*Math.pow(n+1,i);
if (i < k) ret[i] = val;
}
ret is your return array.
It basically finds the base n+1 representation of a, which is the answer they want you to get. If you want more information on why it works, feel free to ask!

Related

My code exceeds the time limit. How can I make my code more optimized?

My code exceeds the time limit at test case 23. I have used dfs to traverse the connected houses. I did everything I could to optimize from my side.
Kattis problem: where's my internet?
import java.util.Scanner;
import java.util.HashMap;
import java.util.ArrayList;
class Main{
static boolean[] isVisited;
static HashMap<Integer, ArrayList<Integer>> hashHouses;
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int numberOfHouses = scanner.nextInt();
int numberOfCables = scanner.nextInt();
hashHouses = new HashMap<>();
for (int i = 1; i < numberOfHouses + 1; i++){
hashHouses.put(i, new ArrayList<Integer>());
}
for (int i = 0; i < numberOfCables; i++){
int x = scanner.nextInt();
int y = scanner.nextInt();
hashHouses.get(x).add(y);
hashHouses.get(y).add(x);
}
isVisited = new boolean[numberOfHouses + 1];
isVisited[1] = true;
dfs(1);
boolean isConnected = true;
for (int i = 1; i < numberOfHouses + 1; i++){
if (!isVisited[i]){
System.out.println(i);
isConnected = false;
}
}
if (isConnected) System.out.println("Connected");
}
static void dfs(int start) {
isVisited[start] = true;
for (Integer i : hashHouses.get(start)) {
if (!isVisited[i]) {
dfs(i);
}
}
}
}
The problem is not in your algorithm.
It is just that input and output in Java is too slow for this online judge.
The solution is to use more efficient input and output code:
For input, use a custom Fast Scanner. See this page for several options.
For output, write the result in a StringBuilder, and then output this StringBuilder with a single System.out.
I was able to pass all the tests on your problem just by applying these two optimisations.

How to overcome this stack overflow issue when finding SCCs?

This is the code I wrote to find SCCs usigng Kosaraju's Two-Passed Algorithm. When I run the main method, I get a StackOverFlowError on SCC.revDFS. How can I avoid the stack overflow error when having a large amount of recursive calls?
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import java.util.Scanner;
public class SCC {
int n = 875714;
Map<Integer,List<Integer>> adjList;
Map<Integer,List<Integer>> adjListRev;
int[] ft;
int t;
int s;
boolean[] marked;
int[] leaders;
public SCC() {
init();
t = 0;
s = 0;
marked = new boolean[n + 1];
leaders = new int[n + 1];
}
void init() {
adjList = new HashMap<Integer,List<Integer>>();
adjListRev = new HashMap<Integer,List<Integer>>();
ft = new int[n + 1];
List<Integer> adj;
try {
Scanner scanner = new Scanner (new InputStreamReader(this.getClass().
getClassLoader().getResourceAsStream("SCC.txt")));
while(scanner.hasNextLine()) {
String s = scanner.nextLine().trim();
String[] num = s.split(" ");
if (!adjList.containsKey(Integer.parseInt(num[0]))) {
adjList.put(Integer.parseInt(num[0]), new ArrayList<Integer>());
}
adj = adjList.get(Integer.parseInt(num[0]));
adj.add(Integer.parseInt(num[1]));
adjList.put(Integer.parseInt(num[0]), adj);
if (!adjListRev.containsKey(Integer.parseInt(num[1]))) {
adjListRev.put(Integer.parseInt(num[1]), new ArrayList<Integer>());
}
adj = adjListRev.get(Integer.parseInt(num[1]));
adj.add(Integer.parseInt(num[0]));
adjListRev.put(Integer.parseInt(num[1]), adj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void DFS_Loop() {
for (int i = 1; i < n + 1; i++) {
marked[i] = false;
}
for (int i = n; i > 0; i--) {
if (!marked[i]) {
revDFS(i);
}
}
for (int i = 1; i < n + 1; i++) {
marked[i] = false;
leaders[i] = 0;
}
for (int i = n; i > 0; i--) {
if (!marked[ft[i]]) {
s = ft[i];
DFS(ft[i]);
}
}
}
public void revDFS(int i) {
marked[i] = true;
List<Integer> edges = adjListRev.get(i);
if (edges != null) {
for (int j: edges) {
if (!marked[j]) {
revDFS(j);
}
}
}
t += 1;
ft[t] = i;
}
public void DFS(int i) {
marked[i] = true;
leaders[s] += 1;
List<Integer> edges = adjList.get(i);
if (edges != null) {
for (int j: edges) {
if (!marked[j]) {
DFS(j);
}
}
}
}
public static void main(String[] args) {
SCC scc = new SCC();
scc.DFS_Loop();
Arrays.sort(scc.leaders);
for (int i = scc.n; i < scc.n - 5; i--) {
System.out.println(scc.leaders[i]);
}
}
}
Maybe you can try to convert the logic to iterative approach. Also, do check if you have base and edge cases handled properly.
The basic idea for converting a recursive function into an iterative function is that a recursive function consumes arguments from a stack.
So you can create a stack and push the values into it and then consume them in a loop.
public void _revDFS(int _i) {
LinkedList<Integer> stack = new LinkedList<>();
stack.push(_i);
while(!stack.isEmpty()){
int i = stack.pop();
marked[i] = true;
List<Integer> edges = adjListRev.get(i);
if (edges != null) {
for (int j: edges) {
if (!marked[j]) {
stack.push(j);
//revDFS(j);
}
}
}
t += 1;
ft[t] = i;
}
}
I can't really test it to see if I made a mistake of some kind and revDFS is a function with a lot of side effect and it does not return a value, so is a bit difficult to reason with it.
But the gist is that instead of calling the function itself you can just push the edge indexes onto the stack and then consume them.
The child edges will be processed in reverse order so if you want to keep the same order of processing of the original you should read the edges in reverse order :
ListIterator<Integer> li = edges.listIterator(edges.size());
while(li.hasPrevious()){
int j = li.previous();
if (!marked[j]) {
stack.push(j);
//revDFS(j);
}
}
you have implemented your Dfs function recursively which causes "stack overflow". To overcome this issue you need to implement it using stack data structure.
see link bellow for more motivations
https://github.com/sinamalakouti/MyFavoriteAlgorithmProblems

Finding largest value in an array from a text file

I'm programming in Java. I'm not good at programming, but I'm trying.
I managed to create a file that generates an array of 10k random (in range 1 through 1 million) numbers into a text file. This class is called 'CreateDataFile'
What I'm trying to do now is read the array from the text file created in 'CreateDataFile' from a completely different class. This new class is called 'ProcessDataFile'
The first thing I thought about doing is 'extends' the class. So both classes communicate.
The thing is, I know how to create a for loop in a program and then find the largest number. I just don't understand how to read this text file, and create a for loop that processes from the text file and finds the max value.
Here's my CreateDataFile class
import java.io.*;
import java.util.Random;
public class CreateDataFile {
public static void main(String[] args) {
int [] integers = new int[10000];
Random r = new Random();
try{
PrintWriter p = new PrintWriter("dataset529.txt");
for (int i = 0; i <integers.length; i++) {
int number = r.nextInt(1000000)+1;
p.print(" " + number);
}
p.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Now this generates the numbers I need into a text file called dataset529.
If everything was in one class, I'd just create a for loop.. something like
int max = integers[0];
for(int i = 0; i<integers.length; i++){
if (integers[i] > max)
System.out.println(integers[i]);
}
But as I'm creating my ProcessDataFile class, I'm having a hard time reading the text file created from the CreateDataFile class.
Any ideas on how I can read this text file and run a for loop over it to find the max number like I used above?
Thanks, any help would be appreciated.
First of all, you should write in the file each number on one line so that it's easier when you read the numbers from the file. This can be done just by doing:
p.print(number + "\n");
After that, you can use this code to get the max of all the numbers:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ProcessDataFile {
public static void main(String[] args) throws IOException {
String fileName = "dataset529.txt";
String temp;
int max = Integer.MIN_VALUE;
int i = 0;
int[] numbers = new int[10000];
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
while((temp = br.readLine()) != null) {
if(temp.isEmpty())
break;
numbers[i++] = Integer.parseInt(temp);
}
}
for(i = 0; i < numbers.length; i++)
if(max < numbers[i])
max = numbers[i];
System.out.println(max);
}
Write the content of each number on new line. While reading the file, maintain a max element.
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
public class CreateDataFile {
public static void main(String[] args) {
int[] integers = new int[10000];
Random r = new Random();
try {
PrintWriter p = new PrintWriter("dataset529.txt");
for (int i = 0; i < integers.length; i++) {
int number = r.nextInt(1000000) + 1;
p.print(number + "\n");
}
p.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Now read the file line by line.
public class ProcessDataFile {
public static void main(String[] args) throws IOException {
int max = Integer.MIN_VALUE;
String line = null;
BufferedReader br = new BufferedReader(new FileReader("dataset529.txt"));
while ((line = br.readLine()) != null) {
int num = Integer.parseInt(line);
if (max < num) {
max = num;
}
}
}
System.out.println(max);
}

Sorting an array using max-heap in Java

I'm working on a program which sorts an array by dividing it into smaller max-heaps and extracting the max-integer out of each one, then deleting it from the heap and running again until every heap is empty, but I can't seem to figure it out.
From where I stand the code looks good, but I don't get the results which I am looking for. My input is created randomly, and makes an array of 512 integers. Here is what it prints for one example run -
Original Array -391 176 -380 -262 -474 327 -496 214 475 -255 50 -351 179 -385 -442 -227 465 127 -293 288
Sorted Array 475 465 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327
n = 20 k = 2
The number of comparisons is 243
Can anyone spot what's wrong with my code? I will be really gladful.
(1) Main Program
import java.io.File;
import java.util.*;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.IOException;
public class Project {
static final int n = 20;
static final int k = 2;
static int counter = 0;
private static Scanner scan;
public static void main(String[] args) throws IOException {
// Optional - reading from a file containing 512 integers.
InputCreator.main();
File f = new File("random.txt");
// File f = new File("increase.txt");
// File f = new File("decrease.txt");
try { scan = new Scanner(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace(); }
int [] L = new int[n];
System.out.print("Original Array ");
for (int i = 0; i < n ; i++)
{ counter++; L[i] = scan.nextInt(); System.out.print(" " + L[i]); }
Projectsort(L);
}
private static void Projectsort(int [] L) {
// int [][] Li = new int [k] [n-(n/k*(k-1))]; // The size of the rest of the integers (n-(n/k*(k-1)) will always be bigger than n/k
int [] temp = new int [n/k], extra = new int [n-(n/k)*(k-1)];
int extraIndex = 0, max, maxIndex = 0, r = 0;
ProjectMaxHeap [] Li = new ProjectMaxHeap [k];
// The following loop's time effiency is O(k) * O(N/k) = O(N)
for (int i=0; i<k-1; i++) { counter++; // copying all the integers from Array L into K-1 smaller arrays
for (int j=0; j<n/k ; j++)
{ counter++; temp [j] = L[i*(n/k)+j]; }
Li[i] = new ProjectMaxHeap (temp); }
for (int i=(n/k)*(k-1) ; i<n ; ++i) // The rest of the integers on array L
{ counter++; extra [extraIndex] = L[i]; extraIndex++; }
Li[k-1] = new ProjectMaxHeap(extra);
System.out.print("\nSorted Array ");
for (int i = n ; i > 0 ; i--) { counter++;
r = 0;
do{max = Li[r].extractMax(); r++; }while(Li[r].isEmpty() && r < k - 1);
for (int j = r; j < k; j++) // Time efficiency O(k)*O(N/k)
{ counter++;
if(!Li[j].isEmpty()) {
if (Li[j].extractMax() > max) {
counter++;
max = Li[j].extractMax();
maxIndex = j; }
}
System.out.print(max + " ");
Li[maxIndex].deleteMax(); } }
System.out.println("\nn = " + n + " k = " + k +"\nThe number of comparisons is " + counter);
}
}
(2) Max Heap Class
public class ProjectMaxHeap
{
private int [] _Heap;
private int _size;
public ProjectMaxHeap (int [] A){
_size = A.length;
_Heap = new int[A.length];
System.arraycopy(A, 0, _Heap, 0, A.length);
for (int i = _size / 2 ; i >=0 ; i--) {
Project.counter++;
maxHeapify(i); }
}
private int parent(int pos)
{ return pos / 2; }
private int leftChild(int pos)
{ return (2 * pos); }
private int rightChild(int pos)
{ return (2 * pos) + 1; }
private void swap(int fpos,int spos) {
int tmp;
tmp = _Heap[fpos];
_Heap[fpos] = _Heap[spos];
_Heap[spos] = tmp; }
private void maxHeapify (int i) {
int l = leftChild(i), r = rightChild(i), largest;
if(l < _size && _Heap[l] > _Heap[i]) {
Project.counter+=2;
largest = l; }
else largest = i;
if(r < _size && _Heap[r] > _Heap[largest]) {
largest = r;
Project.counter+=2; }
if (largest != i) {
Project.counter++;
swap(i, largest);
maxHeapify (largest); }
}
protected boolean isEmpty() { return _size == 0; }
protected void deleteMax() {
if (_size > 1) {
Project.counter++;
maxHeapify(0);
int max = _Heap[0];
_size--;
swap(0, _size);
maxHeapify(0); }
else _size = 0;
}
protected int extractMax() {
maxHeapify(0);
return _Heap[0];
}
}
(3) Input Creator
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.io.FileReader;
import java.io.BufferedReader;
public class InputCreator {
public static void main() {
randomizer();
decrease();
increase();
}
private static void randomizer() {
// The target file
File out = new File("random.txt");
FileWriter fw = null;
int n = 0;
// Try block: Most stream operations may throw IO exception
try {
// Create file writer object
fw = new FileWriter(out);
// Wrap thק writer with buffered streams
BufferedWriter writer = new BufferedWriter(fw);
int line;
Random random = new Random();
while (n < Project.n) {
// Randomize an integer and write it to the output file
line = random.nextInt(1000)-500;
writer.write(line + "\r\n");
n++;
}
// Close the stream
writer.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
private static void increase() {
// The target file
File out = new File("increase.txt");
FileWriter fw = null;
int n = 0;
int temp = 0;
// Try block: Most stream operations may throw IO exception
try {
// Create file writer object
fw = new FileWriter(out);
// Wrap thק writer with buffered streams
BufferedWriter writer = new BufferedWriter(fw);
int line;
Random random = new Random();
while (n < Project.n) {
// Randomize an integer and write it to the output file
line = random.nextInt((n+1)*10);
if(line > temp) {
writer.write(line + "\r\n");
n++;
temp = line; }
}
// Close the stream
writer.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
private static void decrease() {
// The target file
File out = new File("decrease.txt");
FileWriter fw = null;
int n = 0;
int temp = 10000;
// Try block: Most stream operations may throw IO exception
try {
// Create file writer object
fw = new FileWriter(out);
// Wrap thק writer with buffered streams
BufferedWriter writer = new BufferedWriter(fw);
int line;
Random random = new Random();
while (n < Project.n) {
// Randomize an integer and write it to the output file
line = 10000 - random.nextInt((n+1)*20);
if(line < temp) {
writer.write(line + "\r\n");
n++;
temp = line; }
}
// Close the stream
writer.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
}
The problem is with max = Li[0].extractMax(); You are not checking if Li[0] might be empty.
Always check preconditions and fail fast. The problem would have become immediately obvious had you started extractMax and deleteMax with
if (_size == 0) {
throw new IllegalStateException("empty heap");
}
Here's the fixed final loop:
for (int i = 0; i < n; i++) {
int maxIndex = -1; // remove these variable declarations from top of method
int max = Integer.MIN_VALUE; // it's best to confine variables to narrow scope
for (int j = 0; j < k; j++) {
if (!Li[j].isEmpty()) {
int current = Li[j].extractMax();
if (maxIndex == -1 || current > max) {
maxIndex = j;
max = current;
}
}
}
assert maxIndex != -1;
Li[maxIndex].deleteMax();
System.out.print(max + " ");
}

File I/O in Java

I have problems with the code for my own Vector class.
FIXED. Added reading and writing to file, but this try/catch things look too cumbersome for me. Maybe there's a better way of file I/O?
FIXED-2 Oh, I've just discovered "throws" and now my code looks really good. Thanks everyone for help! Here's the final version of Stack.java:
import java.util.Scanner;
import java.io.*;
class Vector {
private int[] vec;
private int length, pointer;
public Vector(int n) {
pointer = 0;
length = n;
vec = new int[length];
}
public int get(int i) {
return vec[i];
}
public void set(int i, int n) {
vec[i] = n;
}
public void push(int n) {
if (pointer == length) {
int[] nvec = new int[length*2];
for (int i = 0; i < length; i++)
nvec[i] = vec[i];
length *= 2;
vec = null;
vec = nvec;
}
vec[pointer++] = n;
}
public void delete() {
pointer--;
if (pointer == length / 4) {
int[] nvec = new int[length/2];
for (int i = 0; i <= pointer; i++)
nvec[i] = vec[i];
length /= 2;
vec = null;
vec = nvec;
}
}
public int size() {
return pointer;
}
public int actualSize() {
return length;
}
}
public class Stack {
public static void main(String[] args) throws IOException {
File ifile = new File("stack1.in");
BufferedReader reader = new BufferedReader(new FileReader(ifile));
File ofile = new File("stack1.out");
BufferedWriter writer = new BufferedWriter(new FileWriter(ofile));
int n = Integer.parseInt(reader.readLine());
Vector stack = new Vector(10);
for (int i = 0; i < n; i++) {
String s = reader.readLine();
if (s.charAt(0) == '-') {
writer.write(Integer.toString(stack.get(stack.size()-1)));
writer.write("\n");
stack.delete();
} else {
s = s.substring(2);
stack.push(Integer.parseInt(s));
}
}
writer.close();
reader.close();
}
}
Your syntax is wrong. Perhaps you meant something like this:
Vector stack = new Vector(10);
Also, are you sure you want your Vector class inside your Stack class? Also also, it's generally a bad idea to name your classes the same thing as existing Java classes.
Initialise the Vector class as below
Vector stack = new Vector(10);
Vector stack = new Vector(10);

Categories

Resources