Alocação dinâmica & Matrizes:

Alocando memória:

Faça uma função em C que aloca dinamicamente memória para uma matriz de inteiros com m linhas e n colunas. A função deve alocar um vetor de apontadores e depois um vetor de inteiros para cada linha (vetor de vetores). O endereço do vetor de apontadores deve ser devolvido pela função.
#include <stdio.h>
#include <stdlib.h>

int **AlocaMatriz(int m, int n){
  int **M;
  int i;

  M = (int **)malloc(sizeof(int *)*m);
  if(M == NULL){
    printf("Memoria insuficiente.\n");
    exit(1);
  }
  for(i = 0; i < m; i++){
    M[i] = (int *)malloc(sizeof(int)*n);
    if(M[i] == NULL){
      printf("Memoria insuficiente.\n");
      exit(1);
    }
  }
  return M;
}
  

Desalocando memória:

Faça uma função em C para liberar toda a memória de uma matriz com m linhas, alocada previamente pela função do item anterior.
void LiberaMatriz(int **M, int m){
  int i;
  for(i = 0; i < m; i++)
    free(M[i]);
  free(M);
}
  

Leitura a partir de arquivo texto:

Escreva uma função que leia uma matriz gravada em um arquivo texto. A função deve receber como parâmetro o nome do arquivo e deve devolver a matriz alocada e preenchida. Assuma a seguinte especificação para os dados gravados no arquivo texto:
Por exemplo, considere o seguinte texto abaixo como um possível conteúdo para um arquivo texto representando uma matriz 10 por 8:
10 8
0  6  0  0  4  0  0  0
0  0  0  0  0  0  7  0
6  9  0  0  1  0  3  0
0  0  1  0  1  0  0  0
0  1  0  1  1  1  0  8
0  1  1  8  1  0  0  0
8  0  0  1  0  0  0  3
0  7  0  1  0  0  0  0
0  0  0  0  0  0  2  0
2  0  5  0  9  0  0  0
Use o protótipo abaixo:

int **LeMatriz(char filename[], int *m, int *n);

onde m aponta para uma variável que irá guardar o número de linhas da matriz alocada, e n aponta para uma variável inteira que irá guardar o número de colunas.

int **LeMatriz(char filename[], int *m, int *n){
  int **M;
  FILE *fp;
  int mm,nn,i,j;

  fp = fopen(filename, "r");
  if(fp == NULL){
    printf("Erro na leitura do arquivo.\n");
    exit(1);
  }
  fscanf(fp,"%d %d",&mm,&nn);
  *m = mm;
  *n = nn;

  M = AlocaMatriz(mm, nn);
  for(i = 0; i < mm; i++){
    for(j = 0; j < nn; j++){
      fscanf(fp,"%d",&M[i][j]);
    }
  }
  fclose(fp);
  return M;
}
  

Problema 01: Matriz delimitadora mínima (Minimum bounding box)

Dada uma matriz de inteiros binária (isto é, contendo valores 0 ou 1), escreva uma função que retorna uma segunda matriz correspondendo ao menor recorte retangular da primeira (submatriz), que contém todos elementos com valores iguais a 1.
Exemplo: Para a matriz:

A saída esperada é:

Use o protótipo abaixo:

int **MatrizDelimitadoraMinima(int **M, int m, int n, int *mm, int *nn);

onde M é uma matriz binária de entrada fornecida, com m linhas e n colunas. Os apontadores mm e nn apontam para duas variáveis inteiras que irão guardar o número de linhas e o número de colunas da matriz de saída alocada, respectivamente.

int **MatrizDelimitadoraMinima(int **M, int m, int n, 
                               int *mm, int *nn){
  int **A;
  int xmin,xmax,ymin,ymax;
  int i,j;

  xmin = n;
  xmax = 0;
  ymin = m;
  ymax = 0;
  for(i = 0; i < m; i++){
    for(j = 0; j < n; j++){
      if(M[i][j] == 0) continue;
      if(j < xmin) xmin = j;
      if(i < ymin) ymin = i;
      if(j > xmax) xmax = j;
      if(i > ymax) ymax = i;
    }
  }
  *mm = ymax - ymin + 1;
  *nn = xmax - xmin + 1;
  A = AlocaMatriz(*mm, *nn);
  for(i = ymin; i <= ymax; i++){
    for(j = xmin; j <= xmax; j++){
      A[i-ymin][j-xmin] = M[i][j];
    }
  }
  return A;
}
  

Exemplo de função principal main:

#include <stdio.h>
#include <stdlib.h>

void ImprimeMatriz(int **M, int m, int n){
  int i,j;
  for(i = 0; i < m; i++){
    for(j = 0; j < n; j++){
      printf(" %2d ",M[i][j]);
    }
    printf("\n");
  }
}


/* Inserir nesse ponto o código das demais funções anteriores */


int main(){
  int **A;
  int **B;
  int mB,nB,mA,nA;

  A = LeMatriz("matrizA.txt", &mA, &nA);
  ImprimeMatriz(A, mA, nA);
  printf("\n");

  B = MatrizDelimitadoraMinima(A, mA, nA, &mB, &nB);

  ImprimeMatriz(B, mB, nB);
  printf("\n");

  LiberaMatriz(A, mA);
  LiberaMatriz(B, mB);
  
  return 0;
}