Flood Fill Recursive algorithm - algorithm

Hello I made use of flood fill recursive algorithm to find the connected cells to each other in an 2D array (Here I am using vectors). But this fails for one boundary test case
#include<iostream>
#include<vector>
using namespace std;
int count = 0;
int max_count = 0;
int min_count = 0;
void floodFillUtil(vector< vector<int> > &a,int i,int j,int m,int n,int prevP,int newN)
{
if (i<0 || i>= m || j<0 || j>=n)
return;
if(a[i][j] != prevP)
return;
count++;
a[i][j] = newN;
floodFillUtil(a,i+1,j+1,m,n,prevP,newN);
floodFillUtil(a,i-1,j-1,m,n,prevP,newN);
floodFillUtil(a,i-1,j+1,m,n,prevP,newN);
floodFillUtil(a,i+1,j-1,m,n,prevP,newN);
floodFillUtil(a,i+1,j,m,n,prevP,newN);
floodFillUtil(a,i,j+1,m,n,prevP,newN);
floodFillUtil(a,i-1,j,m,n,prevP,newN);
floodFillUtil(a,i,j-1,m,n,prevP,newN);
}
void floodFill(vector< vector<int> > &a,int i,int j,int newN,int m,int n) {
int prevP = a[i][j];
floodFillUtil(a,i,j,m,n,prevP,newN);
}
// Driver program to test above function
int main()
{ int m,n;
cin>>m>>n;
vector<vector<int> > a;
vector<int> b;
for(int i=0;i<m;i++)
{for(int j=0;j<n;j++)
{ int temp;
cin>>temp;
b.push_back(temp);
}
a.push_back(b);
b.clear();
}
for(int i=0;i<m;i++)
for(int j=0;j<n;j++) {
if (a[i][j] == 1){
floodFill(a,i,j,2+i,m,m);
min_count = count ;
if(min_count > max_count){
max_count = min_count;
}
count=0;
}
}
for(int i=0;i<m;i++)
{for(int j=0;j<n;j++)
cout<<a[i][j]<<" ";
cout<<endl;}
cout<<max_count;
}
And this is the input test case for which it is failing
8
9
0 1 0 0 0 0 1 1 0
1 1 0 0 1 0 0 0 1
0 0 0 0 1 0 1 0 0
0 1 1 1 0 1 0 1 1
0 1 1 1 0 0 1 1 0
0 1 0 1 1 0 1 1 0
0 1 0 0 1 1 0 1 1
1 0 1 1 1 1 0 0 0
And this is output given by code
0 2 0 0 0 0 2 2 0
2 2 0 0 3 0 0 0 1
0 0 0 0 3 0 3 0 0
0 3 3 3 0 3 0 3 1
0 3 3 3 0 0 3 3 0
0 3 0 3 3 0 3 3 0
0 3 0 0 3 3 0 3 1
3 0 3 3 3 3 0 0 0
27
But the output should be 29, for [1,8] [3,8] and [6,8] it is not changing.What must be the problem in the code.

Looks like a typo here:
floodFill(a,i,j,2+i,m,m);
Should be:
floodFill(a,i,j,2+i,m,n);
Unless your matrix is square. It might be worthwhile to abstract the matrix into an object that knows its own dimensions (see here). Then you can pass fewer parameters everywhere.

Related

How to calculate cost to Convert an N X M binary matrix to all 0 matrix with only allowed moves as square-matrix toggle?

Given an N X M binary matrix ( every element is either 1 or 0) , find the minimum number of moves to convert it to an all 0 matrix.
For converting a matrix, one can choose squares of any size and convert the value of that square. '1' changes to '0' and '0' changes to '1'.This process can be done multiple times with square of the same size. Converting any square counts as 1 move.
Calculate minimum number of moves required..
Example :
input matrix
0 1 1
0 0 0
0 1 1
we need to calculate minimum moves to convert this to all '0' matrix
0 0 0
0 0 0
0 0 0
Here,
For square of size 1 ( 1 X 1 or single element sub-matrix), the total number of moves required to convert this matrix is 4 . he converts elements for position (1,2),(1,3),(3,2),(3,3)
For square of size 2 ( 2 X 2 or single element sub-matrix), it takes 2 moves to convert the matrix
First we can convert elements from (1,2) to (2,3) and the matrix becomes, {{0 0 0}, {0 1 1}, {0 1 1}}
And then we convert elements from (2,2)to (3,3) and the matrix becomes ``{{0 0 0}, {0 0 0}, {0 0 0}}```
So minimum is 2.
Could some help in designing an approach to this ?
I attempted to solve it using Gaussian elimination for every possible square size. But the result is not correct here. There must be some gap in my approach to this problem.
package com.practice.hustle;
import java.util.Arrays;
public class GaussianElimination {
public static void main(String[] args) {
int countMoves = Integer.MAX_VALUE;
byte[][] inputMatrix = new byte[3][3];
inputMatrix[0][0] = 0;
inputMatrix[0][1] = 1;
inputMatrix[0][2] = 1;
inputMatrix[1][0] = 0;
inputMatrix[1][1] = 0;
inputMatrix[1][2] = 0;
inputMatrix[2][0] = 0;
inputMatrix[2][1] = 1;
inputMatrix[2][2] = 1;
int N = inputMatrix.length;
int M = inputMatrix[0].length;
int maxSize = Math.min(N, M);
for (int j = 2; j <= maxSize; ++j) { // loop for every possible square size
byte[][] a = new byte[N * M][(N * M) + 1];
for (int i = 0; i < N * M; i++) { // logic for square wise toggle for every element of N*M elements
byte seq[] = new byte[N * M + 1];
int index_i = i / M;
int index_j = i % M;
if (index_i <= N - j && index_j <= M - j) {
for (int c = 0; c < j; c++) {
for (int k = 0; k < j; k++) {
seq[i + k + M * c] = 1;
}
}
a[i] = seq;
} else {
if (index_i > N - j) {
seq = Arrays.copyOf(a[i - M], N * M + 1);
} else {
seq = Arrays.copyOf(a[i - 1], N * M + 1);
}
}
seq[N * M] = inputMatrix[index_i][index_j];
a[i] = seq;
}
System.out.println("\nSolving for square size = " + j);
print(a, N * M);
int movesPerSquareSize = gaussian(a);
if (movesPerSquareSize != 0) { // to calculate minimum moves
countMoves = Math.min(countMoves, movesPerSquareSize);
}
}
System.out.println(countMoves);
}
public static int gaussian(byte a[][]) {
// n X n+1 matrix
int N = a.length;
for (int k = 0; k < N - 1; k++) {
// Finding pivot element
int max_i = k, max_value = a[k][k];
for (int i = k + 1; i < N; i++) {
if (a[i][k] > max_value) {
max_value = a[i][k];
max_i = i;
}
}
// swap max row with kth row
byte[] temp = a[k];
a[k] = a[max_i];
a[max_i] = temp;
// convert to 0 all cells below pivot in the column
for (int i = k+1; i < N; i++) {
// int scalar = a[i][k] + a[k][k]; // probability of a divide by zero
if (a[i][k] == 1) {
for (int j = 0; j <= N; j++) {
if (a[i][j] == a[k][j]) {
a[i][j] = 0;
} else {
a[i][j] = 1;
}
}
}
}
}
System.out.println("\n\tAfter applying gaussian elimination : ");
print(a, N);
int count = 0;
for (int i = 0; i < N; i++) {
if (a[i][N] == 1)
++count;
}
return count;
}
private static void print(byte[][] a, int N) {
for (int i = 0; i < N; i++) {
System.out.print("\t ");
for (int j = 0; j < N + 1; j++) {
System.out.print(a[i][j] + " ");
}
System.out.println(" ");
}
}
}
Its giving final reduced Euler matrix formed is incorrect and thereby the result is also incorrect.
I think its failing due to the logic used for element like - the cell at index-(2,3) , for that we are not sure which square would it be a part of ( either the square from (1,2) to (2,3) or the square from ( 2,2) to (3,3))
here the input matrix to Gaussian algo is having exactly same sequence at 2nd and 3rd row which could be the culprit of incorrect results.
1 1 0 1 1 0 0 0 0 0
* 0 1 1 0 1 1 0 0 0 1 *
* 0 1 1 0 1 1 0 0 0 1 *
0 0 0 1 1 0 1 1 0 0
0 0 0 0 1 1 0 1 1 0
0 0 0 0 1 1 0 1 1 0
0 0 0 1 1 0 1 1 0 0
0 0 0 0 1 1 0 1 1 1
0 0 0 0 1 1 0 1 1 1
for a sqaure size 2, the above program prints :
Solving for square size = 2
The input to Gaussian algo :
1 1 0 1 1 0 0 0 0 0
0 1 1 0 1 1 0 0 0 1
0 1 1 0 1 1 0 0 0 1
0 0 0 1 1 0 1 1 0 0
0 0 0 0 1 1 0 1 1 0
0 0 0 0 1 1 0 1 1 0
0 0 0 1 1 0 1 1 0 0
0 0 0 0 1 1 0 1 1 1
0 0 0 0 1 1 0 1 1 1
After applying gaussian elimination :
1 0 1 0 0 0 1 0 1 1
0 1 1 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 1 1 0 1 0
0 0 0 0 1 1 0 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1

Shortest Source to Destination Path in a matrix n*m

Given a boolean 2D matrix (0-based index), find whether there is path from (0,0) to (x,y) and if there is one path, print the minimum no of steps needed to reach it, else print -1 if the destination is not reachable. You may move in only four direction ie up, down, left and right. The path can only be created out of a cell if its value is 1.
Example:
Input:
2
3 4
1 0 0 0 1 1 0 1 0 1 1 1
2 3
3 4
1 1 1 1 0 0 0 1 0 0 0 1
0 3
Output:
5
3
Input:
The first line of input contains an integer T denoting the no of test cases. Then T test cases follow. Each test case contains two lines . The first line of each test case contains two integers n and m denoting the size of the matrix. Then in the next line are n*m space separated values of the matrix. The following line after it contains two integers x and y denoting the index of the destination.
Output:
For each test case print in a new line the min no of steps needed to reach the destination.
Code:
bool isSafe(int currRow,int currCol,int rows,int columns,vector<bool> visited[]) {
return currRow>=0 && currRow<rows && currCol>=0 && currCol<columns && !visited[currRow][currCol];
}
int minSteps(vector<int> matrix[],int n,int m,int x,int y) {
vector<bool> visited[n];
for(int i=0;i<n;i++){
vector<bool> tmp(m);
for(int j=0;j<m;j++){
if(matrix[i][j]==0){
tmp[j]=true;
} else {
tmp[j]=false;
}
}
visited[i]=tmp;
}
queue<pair<int,int>> q;
q.push(make_pair(0,0));
visited[0][0]=true;
int minDist[n][m];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
minDist[i][j]=INT_MAX;
}
}
minDist[0][0]=0;
static int rows[]={0,1,0,-1};
static int columns[]={1,0,-1,0};
while(!q.empty()) {
pair<int,int> p=q.front();
q.pop();
for(int i=0;i<4;i++) {
if(isSafe(p.first+rows[i],p.second+columns[i],n,m,visited)) {
visited[p.first+rows[i]][p.second+columns[i]]=true;
q.push(make_pair(p.first+rows[i],p.second+columns[i]));
if(minDist[p.first+rows[i]][p.second+columns[i]]> minDist[p.first][p.second]+1) {
minDist[p.first+rows[i]][p.second+columns[i]] = minDist[p.first][p.second]+1;
}
}
}
}
if(minDist[x][y]!=INT_MAX) {
return minDist[x][y];
}
return -1;
}
Test Case Failing
Input:
20 13
0 1 1 1 1 0 0 0 1 1 1 1 0 0 0 0 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 1 0 1 0 1 1 0 0 0 1 1 0 1 1 0 1 1 1 0 1 1 0 1 0 1 1 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 1 1 0 1 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 1 1 1 1 1 0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 1 0 1 0 0 0 0 1 1 1 1 0 0 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1 1 0 1 1 0 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 1 1 0 1 0 0 1 1 1 0 1 0 1 0 1 0 0 0 0 1 0 1 1 0 1 0 0 1 1 0 0 0 1 0 1 1 1 1 0 0 1 0 0 0 0 1 0 0 1 1 1 1 0 0 1 1 1 0 1
6 3
Its Correct output is:
-1
And Your Code's output is:
13
Algorithm:
1. Traverse the 2 d array from source using BFS.
2. Maintain 2 2d arrays visited and minDist.
3. Initialize values of visited as true whose value in array is 0 and rest as false; Initialize minDist to INT_MAX.
4. While traversing, validate if its a valid point using isSafen where it is checked if visited is false and point lies within 2d array size limits.
5. If point is safe, make visited for the point as true and push it in the queue.
6. Finlly check if mindist for the point is greater than its parent minDist + 1 ; Update accordingly.
But i am getting wrong answer; attached failing test case. Can someone explain where my algo is going wrong ?
I have the missed below corner case:
If matrix[0,0] == 0
return -1
Now, algorithm passes all test cases.

construct a matrix in Octave

I have a vector idx = [3; 5; 3; 4; 3; 2; 5; 1]. The number is from 1:k with k = 5. I want to make a "k by m" matrix A (m is the number of elements in the vector idx). Each row of A contains either '0' or '1' with '1' indicated by the index of the vector idx. For example, the third row of A (k = 3) is "1" at columns 1, 3, 5 because those are the indexes of "3" in idx. So that A =
[0 0 0 0 0 0 0 1; 0 0 0 0 1 0 0 0; 1 0 1 0 1 0 0 0; 0 0 0 1 0 0 0 0; 0 1 0 0 0 0 1 0]
How can I do this in Octave? Thank you!
Or another way:
idx = [3; 5; 3; 4; 3; 2; 5; 1];
A = sparse (idx, [1:numel(idx)], 1)
A = Compressed Column Sparse (rows = 5, cols = 8, nnz = 8 [20%])
(3, 1) -> 1
(5, 2) -> 1
(3, 3) -> 1
(4, 4) -> 1
(3, 5) -> 1
(2, 6) -> 1
(5, 7) -> 1
(1, 8) -> 1
Which gives you a compressed column sparse (very efficient), you can convert this to a "normal, full matrix":
B = full (A)
B =
0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0
1 0 1 0 1 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 1 0
Try this:
idx = [3; 5; 3; 4; 3; 2; 5; 1];
n = numel(idx);
k = 5;
A=zeros(k,n);
A(sub2ind(size(A), idx, [1:n]')) = 1
Output is:
A =
0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0
1 0 1 0 1 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 1 0

Matlab file input

I am asking this as a person with no experience in Matlab.
The project is simple; write a code to analyse a simple truss. The following is what a team mate has been working on - I'm supposed to write the input file:
file = input('File Input): ', 's');
run(file)
%Cc corresponds to # of joints and Rc corresponds to # of members
[Rc Cc] = size(C);
%JM is a matrix that contains the joint numbers that each member is
%connected to. The row number is the member number
JM = zeros(Cc, 2);
%x components
Ax = zeros(Rc, Cc);
%y components
Ay = zeros(Rc, Cc);
My_total_length = 0;
Member_length = 0;
%finding JM matrix which stores the joints that each member is connected to
%loop through C matrix and store the joint number each member is connected
%to
for j = 1:Cc
counter = 0;
for i = 1:Rc
if C(i,j) == 1
counter = counter + 1;
JM(j, counter) = i;
end
end
end
%using JM, loop through C again and create the equilibrium equations using
%the locations of each joint X and Y
for j = 1:Cc
counter = 3;
for i = 1:Rc
if C(i,j) == 1
%use counter to get x2 - x1 from JM vector
counter = counter - 1;
%find x and y distance of member and divide it by length of the member
Member_length = sqrt(((X(JM(j,2))) - ...
(X(JM(j,1))))^2 + ((Y(JM(j,2))) - (Y(JM(j,1))))^2);
Ax(i,j) = (X(JM(j,counter)) - X(i)) / Member_length; ! 13!
Ay(i,j)= (Y(JM(j, counter)) - Y(i)) / Member_length;
end
end
My_total_length = My_total_length + Member_length;
end
%combine the 4 matrices to create the larger matrix A
A = [Ax Sx; Ay Sy];
%define the vector for the forces on each member
T = zeros(Cc +3, 1);
T = inv(A)*-L;
%OUTPUT
%Find what the load on the truss is by looping through the weight vector and finding the load
for i=1:length(L)
if L(i) ~= 0
Load = L(i);
end
end
%Display load
fprintf('Load: %f N \n',Load)
%Display the forces on the members. Loop through Vector T up to the where reaction forces are
fprintf('Member forces in Newtons: \n')
for i = 1:length(T)-3
if (T(i)<0)
fprintf('m%d: %2.3f (C) \n', i, abs(T(i)))
elseif (T(i)==0)
fprintf('m%d: %d \n', i, abs(T(i)))
else
fprintf('m%d: %2.3f (T) \n', i, abs(T(i)))
end
end
%Display the last three items of vector T, the reaction forces
fprintf('Reaction forces in Newtons: \nSx1: %2.3f \nSy1: %2.3f \nSy2: %2.3f \n'...
, T(length(T)-2), T(length(T)-1), T(end))
%Calculate cost of truss
Cost = Rc*(10) + My_total_length*(1);
%Display the cost of truss
fprintf('Cost of truss: $%3.2f \n', Cost)
%Display load/cost ratio
fprintf('Theoretical max load/cost ratio in N/$: %2.4f \n', (Load/Cost))
Now, the problem I have is actually the input file. What kind of file should I save it as? How do I write it in the file? When I'm trying to run the code and need to access the file, how do I write the file name (with .txt after)? Some of the information that has to go into the file is below:
Sx = [ 1 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0, 0 0 0; 0 0 0]
Sy = [ 0 1 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 0; 0 0 1]
C = [ 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ; 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0; 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1]
L = [ 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 500; 0; 0; 0; 0; 0]
X = [ 0,6,12,18,24,30,36,42,48,54,60]
Y = [ 0,8,0,8,0,8,0,8,0,8,0]
Would truly appreciate any help.
You can use fwrite to write to a txt file. This does however need fread and so code to read it into matlab again. xlswrite and xlsread does the same for xls files.
However, the simplest way if a file only is to be used together with matlab is to use the functions load and save. You can read the help for them with help save or help load, but the can save one or more variables to a .mat file.
a = 1;
b = 'e';
c = [1,2;3,4];
d = struct('hi',1,'you','e');
save('myFileName.mat','a','b','c','d');
clear;
load('myFileName.mat')
You can also write filepath/filename (or \ for windows) where filepath is the full path.

Finding a minimal set of rectangles covering a binary matrix [duplicate]

This question already has answers here:
Algorithm for finding the fewest rectangles to cover a set of rectangles without overlapping
(2 answers)
Closed 5 years ago.
Say I have the following binary matrix:
0 0 0 1 1 1 0
0 0 0 1 1 1 0
0 0 0 1 1 1 0
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
0 0 0 1 1 1 0
0 0 0 1 1 1 0
0 0 0 1 1 1 0
I want to find the set of rectangles parallel to the x and y axis that covers every 1 at least once and covers not a single 0 which has minimal cardinality (the least amount of rectangles). In the example above this would be the rectangles ((0, 3), (6, 5)) and ((3, 0), (5, 8)) (notation is in the form (topleft, bottomright)) - the minimal solution is using two rectangles.
My previous attempt was finding the rectangle with the largest area covering only 1's, adding that rectangle to the set and then marking all those 1's as 0's, until all 1's are gone. While this set would cover every 1 and not a single 0, it won't necessarily have minimal cardinality (this algorithm will fail on the example above).
I think you should replace covered 1's with 2's instead of 0's. This way you can include the 2's when covering 1's and still not cover any 0's.
Here's what I came up with:
#include <stdio.h>
#include <stdlib.h>
struct board {
int **data;
int w,h;
};
int load_board(char *, struct board *);
void print_board(struct board *);
int max_height_with_fixed_w(struct board *board, int i, int j, int w) {
int jj = -1, ii;
if (board->data[j][i] != 0) {
for (jj = j; jj < board->h && board->data[jj][i] != 0; jj++) {
for (ii = i; ii - i < w; ii++) {
if (board->data[jj][ii] == 0)
return jj - j;
}
}
printf("maximum height = %d\n", jj);
}
return jj - j;
}
void find_largest_rect_from(
struct board *board,
int i, int j, int *ei, int *ej) {
int max_w = 0, max_h = 0, max_a = 0;
*ei = *ej = -1;
for (max_w = 0; max_w < board->w - i &&
(board->data[j][i + max_w] != 0);
max_w++) {
int max_aa;
int max_hh = max_height_with_fixed_w(board, i, j, max_w + 1);
if (max_hh > max_h) {
max_h = max_hh;
}
max_aa = max_hh * (max_w + 1);
printf(" area: %d x %d = %d\n", max_hh, max_w + 1, max_aa);
if (max_aa > max_a) {
max_a = max_aa;
*ei = i + max_w;
*ej = j + max_hh - 1;
}
}
printf("max width : %d\n", max_w);
printf("max height: %d\n", max_h);
printf("max area : %d\n", max_a);
}
int main(int arc, char **argv) {
struct board board;
int jj, ii, i = 0, j = 0;
int total_rects = 0;
if(load_board(argv[1], &board)) return 1;
print_board(&board);
for (j = 0; j < board.h; j++) {
for (i = 0; i < board.w; i++) {
if (board.data[j][i] == 1) {
find_largest_rect_from(&board, i, j, &ii, &jj);
printf("largest from %d, %d ends at %d,%d\n", i, j, ii, jj);
int marki, markj;
total_rects++;
for (markj = j; markj <= jj; markj++) {
for (marki = i; marki <= ii; marki++) {
board.data[markj][marki] = 2;
}
}
print_board(&board);
}
}
}
printf("minimum %d rects are required\n", total_rects);
return 0;
}
int load_board(char *fname, struct board *board) {
FILE *file = fopen(fname, "r");
int j,i;
if (!file) return 1;
fscanf(file, "%d %d", &board->w, &board->h);
board->data = (int**)malloc(sizeof(int*)*board->h);
for (j = 0; j < board->h; j++) {
board->data[j] = (int*)malloc(sizeof(int)*board->w);
for (i = 0; i < board->w; i++) {
fscanf(file, "%d", &board->data[j][i]);
}
}
return 0;
}
void print_board(struct board *board) {
int i,j;
printf("board size: %d, %d\n", board->w, board->h);
for (j = 0; j < board->h; j++) {
for (i = 0; i < board->w; i++) {
printf("%d ", board->data[j][i]);
} printf("\n");
}
}
Example input 1:
7 9
0 0 0 1 1 1 0
0 0 0 1 1 1 0
0 0 0 1 1 1 0
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
0 0 0 1 1 1 0
0 0 0 1 1 1 0
0 0 0 1 1 1 0
Example input 2:
7 7
0 0 0 1 0 0 0
0 0 1 1 1 0 0
0 1 1 1 1 1 0
1 1 1 1 1 1 1
0 1 1 1 1 1 0
0 0 1 1 1 0 0
0 0 0 1 0 0 0
Idea for an algorithm:
As long as there are 1s in the matrix do:
For every 1 that doesn't have 1 above it AND doesn't have 1 to its left, do:
Go greedy: start from this 1 and go in diagonal to the right and down, as long as there are 1s on the way - create a rectangle and change the 1s of the created rectangle into 0s.
I'd go for an algorithm that picks points and expands until it comsumed all possible space, and then picks more, until all points on the grid have been consumed.
For your example, say we're consuming 1s.
I'll pick (0,3), the uppermost of the leftmost 1s. My rectangle would start at a size of 0,0. I'd expand it right and down until it grew to a size of 6,2. At this point, I'd mark those points as occupied.
I'd then pick another point, say (3,0), with a rectangle of size 0,0. I'd grow it down and right until it took up the largest available space, at a size of 2,6.
Consider the following:
0 0 0 1 0 0 0
0 0 1 1 1 0 0
0 1 1 1 1 1 0
1 1 1 1 1 1 1
0 1 1 1 1 1 0
0 0 1 1 1 0 0
0 0 0 1 0 0 0
You can easily determine that for any random starting points, it will always take 4 rectangles.
In order to mark points as "occupied", you should mark them differently than those marked "unconsumable". You can then differentiate between unconsumable (which cannot be expanded into) and "occupied" (which may be expanded into, but do not have to be since they already have been).

Resources