1. There is. txt file of the following form:

3 2
12

12
2 4

4 2
13

12
2 1

Where are the first 4 digits: 3 is the number of matrices in the file (any number is not more than 130) 2 is the size of matrices (they are always square, any size is not more than 130) 1, 2 -i, j of the desired element of the resulting matrix All other numbers below are matrices themselves:

1 2 matrix 1
3 4

4 2 matrix 2
13

1 2 matrix 3
2 1

  1. Need to do. As a result, you need to output to the file the number from the resulting matrix with the coordinates for the row and column specified in the file (1, 2 in the given example). The resulting matrix is ​​the matrix obtained by multiplying the matrices from the file. In the above case, the answer is: 20

My code is:

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 { StreamTokenizer tokenizer=new StreamTokenizer(new BufferedReader(new FileReader("input.txt"))); //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(m>=1 && m<=130 && n>=1 && n<=130 && a>=1 && a<=n && b>=1 && b<=n){ fileCheckOk=true; //check if input values are comply with task conditions }*/ } 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; } } } } 

The code works and gives the correct answer. But does not pass tests because of too slow work. What could be the path of acceleration?

1 Maybe another internal matrix multiplication algorithm? Now they are multiplied "in the forehead":

 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 like that. A little faster (see the calculate method).

2 Can be split calculations on separate threads?

3 Maybe another way to handle file data? Now each subsequent integer number of the file, the first 4 are assigned to variables, all others are driven into a one-dimensional array. From which we then take the values ​​to create matrices that are multiplied.

Something like this.

  • one
    try the solution with StreamTokenizer from acm.timus.ru/help.aspx?topic=java - zRrr
  • Thanks for the advice. Used StreamTokenizer. Measurements of the execution time of the code show that the speed of reading data from the file has increased significantly. However, the code still fails, falling on all the same test due to exceeding the time limit. On this basis, I assume that the way of reading the file data as such from those suspected of the reason for the failure of the code to speed can be excluded. - pazukdev
  • try all the same as in the instruction with wrapping in BufferedReader ( new StreamTokenizer(new BufferedReader(new FileReader(file))); ) - zRrr
  • I tried. The result is the same. - pazukdev

0