I need to write a program for the problem below :
you have a lawn (a matrix of n*m) and in some cells, weed has grown, and you want to remove them.
there are two operations :
stomping on a cell: by doing so, one of the weeds in that cell dies and two new weeds appear in cells [i][(j+1)%n) and [(i+1)%n][j].
pulling out a weed: this removes the weed and takes the energy of E_(i,j).
Now given a matrix of energy(how much energy removing one weed from each cell takes) and the places where weeds have grown, we want to calculate the least amount of energy we need to get rid of all the weeds.
import java.util.Scanner;
import java.util.*;
import java.io.*;
public class TEST{
public static void main (String[] args)
{
int n=0, m=0 , k=0;
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
m = scanner.nextInt();
k = scanner.nextInt();
scanner.nextLine();
int [][] lawn = new int [n][m];
int [][] NumOfWeed = new int [n][m];
for(int j=0; j<m ; j++){
for(int i=0; i < n ; i ++){
lawn[i][j]= scanner.nextInt();
}
scanner.nextLine();
}
int i_index =0, j_index =0;
for(int i=0; i < k ; i ++){
i_index= scanner.nextInt();
j_index=scanner.nextInt();
scanner.nextLine();
NumOfWeed[i_index][j_index] ++;
}
boolean changing = true;
while(changing){
changing = false;
for(int j=0; j<m ; j++){
for(int i=0; i < n ; i ++){
if(NumOfWeed[i][j]>0){
if(lawn[i][j] > lawn[(i+1)%n][j]+lawn[i][(j+1)%n]){
NumOfWeed[(i+1)%n][j] =NumOfWeed[(i+1)%n][j] + NumOfWeed[i][j];
NumOfWeed[i][(j+1)%n] = NumOfWeed[i][(j+1)%n] + NumOfWeed[i][j];
NumOfWeed[i][j]=0;
changing = true;
}
}
}
}
}
int sumEnergy =0;
for(int j=0; j<m ; j++){
for(int i=0; i < n ; i ++){
sumEnergy = sumEnergy + lawn[i][j]*NumOfWeed[i][j];
}
}
scanner.close();
System.out.println(sumEnergy);
}
}
you can see my own code above, but as you see it's not optimal at all.
any ideas on how I can change it so that it takes less time to perform?
Here is one way of doing it, that should lead to correct results but isn't optimized:
Initialize a matrix a (size n * m) for the actual energy needed if you stomp optimally. Set all values to -1.
Find all minima in the original energy matrix ignoring values where the corresponding position in a is not -1. Set the positions of the minima in a to its value.
While there are changes and a isn't completely filled do the following: For each value (i, j) in a that is -1 and the values to the right and down (with wrap-around) are not -1 set (i, j) to the minimum of the sum of the 2 stomped position and the original energy needed for (i, j).
Continue with 2. until a is completely filled. Then "multiply" the lawn matrix with a (no matrix multiplication, just same position with same position) and sum up the values to get the total.
Related
1 What I have on input
File input.txt looking like this:
3 2
1 2
1 2
3 4
4 2
1 3
1 2
2 1
Where:
3 2 3-number of matrices in file; 2-length of matrices (they all square)
1 2 i=1 j=2 -positions of requested value inmatrixResult[i][j]
1 2 matrix 1
3 4
4 2 matrix 2
1 3
1 2 matrix 3
2 1
Number of matrices can be any <=130
Matrices size can be any <=130
2 What should I have on output
One number, which is member of result matrix, specified by position values (1, 2 in this case).
Where result matrix=matrix 1 * matrix 2
For example final result is: 20
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
/**
* Created by Pazuk on 28.01.2018.
*/
// Main idea:
// Step 1. Get all values from input file and according with it build array with numbers for matrices
// Step 2.
// Loop iteration:
// - get numbers from array and create next matrix array
// - multiply actual matrix with next matrix, get result matrix
// - mark result matrix as actual matrix
// Next iteration...
// Step 3. After last iteration, get from result matrix requested number (positions specified in input file)
public class Main {
static int[] list;
static boolean fileCheckOk=true;
static int m;
static int n;
static int a;
static int b;
static int[][] matrixA;
public static void main(String[] args) throws IOException {
long startTime = System.currentTimeMillis();
long time = System.currentTimeMillis() - startTime;
System.out.println(time);
readFile();
time = System.currentTimeMillis()-startTime;
System.out.println(time);
if(fileCheckOk){
calculate();
PrintWriter writer=new PrintWriter("output.txt");
writer.print(matrixA[a-1][b-1]);
writer.close();
}
time = System.currentTimeMillis()-startTime;
System.out.println(time);
}
static void readFile() throws IOException {
Reader reader=new FileReader(file);
StreamTokenizer tokenizer=new StreamTokenizer(reader);
//general input values:
tokenizer.nextToken();
m=(int)tokenizer.nval; // number of matricis
tokenizer.nextToken();
n=(int)tokenizer.nval; // matrices size
tokenizer.nextToken();
a=(int)tokenizer.nval; // position i of requested number
tokenizer.nextToken();
b=(int)tokenizer.nval; // position j of requested number
list=new int[m*n*n]; // array length according with quantity of matricis and their size
int i=0;
while(tokenizer.nextToken()!=StreamTokenizer.TT_EOF){
list[i]=(int)tokenizer.nval;
i++;
}
if(reader!=null) {
reader.close();
}
/*if(m>=1 && m<=130 && n>=1 && n<=130 && a>=1 && a<=n && b>=1 && b<=n){
fileCheckOk=true;
}*/
}
static void calculate(){ // calculate matrices
int f, i, j, k;
int r=0;
int t;
int temp;
int[] thatColumn=new int[n];
int[] thisRow=new int[n];
int result=0;
matrixA=new int[n][n]; // actual matrix
for(f=0; f< m; f++){ // number of iterations==matrices quantity
int[][] matrixB=new int[Main.n][Main.n]; // next matrix
for(i=0; i< Main.n; i++){
for(j=0; j< Main.n; j++){
matrixB[i][j]=list[r];
r++;
}
}
if(f>0){
int[][] matrixC=new int[Main.n][Main.n]; //result matrix
for(j=0; j< Main.n; j++){
for(k=0; k< Main.n; k++){
thatColumn[k]=matrixB[k][j];
}
for(i=0; i< Main.n; i++){
thisRow=matrixA[i];
result=0;
for(k=0; k<Main.n; k++){
temp=thisRow[k]*thatColumn[k];
result=result+temp;
}
matrixC[i][j]=result;
}
}
/*for(i=0; i< Main.n; i++){
for(j=0; j< Main.n; j++){
t=matrixA[i][k];
for(j=0; j< Main.n; j++){
temp=t*matrixB[k][j]; // multiplying...
matrixC[i][j]=matrixC[i][j]+temp; // ...matrces
}
}
}*/
matrixA=matrixC;
} else {
matrixA=matrixB;
}
}
}
}
My code works and gives on output right value. But this code don't pass test. Because of it works too slow.
What can I do to make this do it faster?
Maybe #1. Process info from file other way? Now i scan nextInt. First
4 put into variables. All left into int[ ] array ( look readFile() method ).
And after take values for A, B, ect. matrices from this array.
Maybe #2. Change way of multiplying of matrices? Now I do it with
basic "direct" way:
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
for(int k=0; k<o; k++){
resultMatrix[i][j]+=mA[i][k]*mB[k][j];
}
}
}
Well, almost this way. A bit faster ( look calculate( ) method ).
Maybe #3. Make calculations (or something other) in parallel threads?
Maybe #4. Instead of: "build" A and B matrices from int[ ] array values
at first for multiply them after Try to: make calculation of
resultMatrix using directly values from one-dimensional array int [ ]?
Im currently writing some code that print Pascal's Triangle. I need to use a 2D array for each row but don't know how to get the internal array to have a variable length, as it will also always changed based on what row it is int, for example:
public int[][] pascalTriangle(int n) {
int[][] array = new int[n + 1][]
}
As you can see I know how to get the outer array to have the size of Pascal's Triangle that I need, but I don't know how to get a variable length for the row that corresponds with the line it is currently on.
Also how would I print this 2D array?
Essentially what you want to happen is get the size of each row.
for(int i=0; i<array.size;i++){//this loops through the first part of array
for(int j=0;j<array[i].size;j++){//this loops through the now row
//do something
}
}
You should be able to use this example to also print the triangle now.
This is my first answer on StackOverFlow. I am a freshman and have just studied Java as part of my degree.
To make every step clear, I will put different codes in different methods.
Say n tells us how many rows that we are going to print for the triangle.
public static int[][] createPascalTriangle(int n){
//We first declare a 2D array, we know the number of rows
int[][] triangle = new int[n][];
//Then we specify each row with different lengths
for(int i = 0; i < n; i++){
triangle[i] = new int[i+1]; //Be careful with i+1 here.
}
//Finally we fill each row with numbers
for(int i = 0; i < n; i++){
for(int j = 0; j <= i; j++){
triangle[i][j] = calculateNumber(i, j);
}
}
return triangle;
}
//This method is used to calculate the number of the specific location
//in pascal triangle. For example, if i=0, j=0, we refer to the first row, first number.
public static int calculateNumber(int i, int j){
if(j==0){
return 1;
}
int numerator = computeFactorial(i);
int denominator = (computeFactorial(j)*computeFactorial(i-j));
int result = numerator/denominator;
return result;
}
//This method is used to calculate Factorial of a given integer.
public static int computeFactorial(int num){
int result = 1;
for(int i = 1; i <= num; i++){
result = result * i;
}
return result;
}
Finally, in the main method, we first create a pascalTriangle and then print it out using for loop:
public static void main(String[] args) {
int[][] pascalTriangle = createPascalTriangle(6);
for(int i = 0; i < pascalTriangle.length; i++){
for(int j = 0; j < pascalTriangle[i].length; j++){
System.out.print(pascalTriangle[i][j] + " ");
}
System.out.println();
}
}
This will give an output like this:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
I am very new to Java and I was trying to solve this problem on Hackerrank:
Here's the task:
https://www.hackerrank.com/challenges/cut-the-sticks
You are given N sticks, where the length of each stick is a positive
integer. A cut operation is performed on the sticks such that all of
them are reduced by the length of the smallest stick.
Suppose we have six sticks of the following lengths:
5 4 4 2 2 8
Then, in one cut operation we make a cut of length 2 from each of the six
sticks. For the next cut operation four sticks are left (of non-zero length), > whose lengths are the following:
3 2 2 6
The above step is repeated until no sticks are left.
Given the length of N sticks, print the number of sticks that are left before > each subsequent cut operations.
Note: For each cut operation, you have to recalcuate the length of smallest
sticks (excluding zero-length sticks).
Here is my attempt at it, but it doesnt seem to be working. The output gets stuck in while loop (4 gets printed out infinitely)
import java.io.*;
import java.util.*;
public class Solution {
private static int findMin (int[] A)
{
int min = A[0];
for (int i =0; i<A.length; i++)
{
if (A[i] < min)
{
min = A[i];
}
}
return min;
}
private static int countNonZeros (int[] A)
{
int zeros = 0;
for (int i =0; i<A.length; i++)
{
if (A[i] == 0)
{
zeros++;
}
}
int nonZeros = A.length - zeros;
return nonZeros;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] A = new int[n];
for (int i=0; i<n; i++)
{
A[i] = scanner.nextInt();
}
int nums = countNonZeros(A);
while (nums > 0)
{
int mins = findMin(A);
for (int j = 0; j<A.length; j++)
{
A[j]=A[j]-mins;
}
nums = countNonZeros(A);
System.out.println(nums);
}
}
}
Any help is appreciated
(PS I know I can just look the solution up somewhere, but I want to know why my code isn't working)
The problem that you have is that your findMin is not excluding zero-length elements, so once you have a zero that will be the min, and as a result an iteration of the while loop will be the same as the previous iteration, having subtracted 0 from each of the elements of A.
I have the following code in which a matrix is defined through system input:
import java.io.*;
import java.util.*;
public class Test {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//define size of matrix
int size = in.nextInt();
int primeSum = 0;
int secSum = 0;
int[] matrix = new int[size*size];
//create matrix
for (int i=0; i<size*size;i++) {
matrix[i] = in.nextInt();
}
in.close();
//sum primary diagonal
for (int i=0; i < size*size;i += (size + 1)) {
primeSum = primeSum + matrix[i];
}
////sum secondary diagonal
// for (int i=(size - 1); i < size*size; i += (size - 2)) {
// secSum = secSum + matrix[i];
// }
System.out.println(Math.abs(secSum - primeSum));
}
}
The code above works in that it allows the user to define an NxN matrix through inputting N as the size - so in the case size = 2 the user would define 4 matrix elements. However, after commenting back in the code for the secondary diagonal, the scanner object keeps expecting input past 4 integers - I have no idea why this would affect the program as I close the input stream before that block of code is reached.
You wrote a potentially infinite loop. I.e. if size is not greater than 2, then i will count down or stay 0. You should cover these corner cases, then your code will be fine.
As far as I can see, you're emulating a two-dimensional array on a one-dimensional. This is something that's hard to understand and easy to mess up. You are better off with a two-dimensional array and some nested loops:
int[][] matrix = new int[size][size];
//create matrix
for (int i=0; i<size; i++) {
for (int j=0; j<size; j++) {
matrix[i][j] = in.nextInt();
}
}
// and so on...
Your this part of code:
for (int i=0; i<size*size;i++) {
matrix[i] = in.nextInt();
}
calls the method nextInt which demands for input as long as the array is filled.
This is the original prompt:
Write program that declares a 2-dimensional array of doubles called scores with three rows and three columns. Use a nested while loop to get the nine (3 x 3) doubles from the user at the command line. Finally, use a nested for loop to compute the average of the doubles in each row and output these three averages to the command line.
Here is my code:
import java.util.Scanner;
public class Scorer {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
double [][] scores = new double[3][3];
double value = 0;
int i = 0;
int j;
while (i < 3) {
j = 0;
while (j < 3) {
System.out.print("Enter a number: ");
value = scnr.nextDouble();
scores[i][j] = value;
j++;
}
i++;
}
int average = 0;
for (i = 0; i < scores.length; i++) {
for (j = 0; j < scores[i].length; j++) {
average += value;
value = value / scores[i][j];
System.out.println(value);
}
}
}
}
The part that I need help on is the nested for loop at the bottom of the code. This code is supposed to compute the average of the numbers that are entered; however, I am confused on how to do that with the nested for loop.
you're almost there!
Here are the things you need to do:
1)you've to initialize the variable 'average' after the first for loop.
because average needs to be 0 i.e., reset after second for loop ends each time.
2)you've defined "value = value / scores[i][j]" . I don't know why you did that, but "value = scores[i][j]" must solve your problem.
3) you should print the average only thrice i.e., after calculating average of each row. so, print average at the end of second for loop.
Hope this makes it clear.
here's the code for your reference:
for (i = 0; i < 3; i++) {
int average = 0;
for (j = 0; j < 3; j++) {
value = scores[i][j];
average += value;
}
System.out.println(average/3);
}
Ever i represents a row, every j represents a column.
You need the average of every row, meaning that for every same i and every different j for that i you need to store the values and calculate the average.
Looks like homework code. We can give you hints but not write it for you :(