Faça um algoritmo computacional para ler uma matriz e escrever suas diagonais (principal e secundária). A implementação deve ser feita em C (ou C++), usando vetores no estilo de C (ou da biblioteca std) e no MATLAB/Scilab.
Passo 1
O que o enunciado pede:
- Criar algoritmos que leiam uma matriz e escrevam suas diagonais: a diagonal principal e a diagonal secundária.
- Implementações pedidas: em C (ou C++ com std::vector) e em MATLAB/Scilab.
Dados de entrada e saída esperados: - Entrada: número de linhas e colunas da matriz (digamos
e ) e os elementos da matriz, lidos linha a linha. - Saída: os elementos da diagonal principal e os elementos da diagonal secundária, impressos (por exemplo, numa linha cada uma, separados por espaços).
Observações importantes sobre o enunciado: - O enunciado não diz explicitamente que a matriz é quadrada. Portanto, vamos tratar o caso geral
(se é o caso quadrado usual). - Nada será lido da figura — não há figura. Vou assumir leitura padrão (stdin) para os códigos.
Passo 2
Entender o que são as diagonais em termos de índices (muito importante para implementar sem erro).
- Índices: em linguagens estilo C/C++ usamos índices 0-based: linhas vão
, colunas . - Em MATLAB/Scilab os índices são 1-based: linhas
, colunas .
Diagonal principal:
- Em 0-based, os elementos da diagonal principal são aqueles cuja linha e coluna coincidem, isto é, os índices
com . - Em 1-based, são
com .
Diagonal secundária:
- Em 0-based, a condição típica para a secundária é
, isto é, na linha o elemento da secundária está na coluna . Para que esse exista precisamos ter . - Em 1-based, a relação equivalente é
, ou seja , e devemos ter . - Observação para matrizes não quadradas: ainda podemos obter elementos da secundária testando se a coluna calculada está dentro dos limites. Assim a definição funciona para retangulares também (pode resultar em menos elementos que a principal se
ou vice-versa).
Passo 3
Algoritmo geral (pseudocódigo) que serve para todas as implementações:
- Ler inteiros
e . - Alocar/ler matriz
com linhas e colunas, preenchida linha a linha. - Para a diagonal principal:
- Para
de até : imprimir .
- Para
- Para a diagonal secundária (0-based):
- Para
de até : - calcular
. - se
então imprimir .
- calcular
- Para
- (Em MATLAB/Scilab, adaptar índices para 1-based: usar
e .)
Passo 4
Explicação por que o pseudocódigo funciona e complexidade:
- Leitura da matriz custa
, necessária pois precisamos de todos os elementos. - A extração de cada diagonal visita no máximo
elementos (cada diagonal), portanto . - Espaço: precisa armazenar a matriz
se quisermos ler tudo antes; poderia-se imprimir diagonais durante a leitura em casos especiais, mas aqui usamos leitura completa pela clareza. - Casos de atenção na prova: índice 0-based vs 1-based; cuidado com matriz não quadrada; elemento central em matriz quadrada ímpar aparece em ambas as diagonais — isso é normal.
Passo 5
Detalhes de implementação em C (estilo C, vetores como bloco linear):
- Vou armazenar a matriz em um vetor linear de comprimento
. A posição corresponde ao índice linear . - Leitura: usar scanf para ler
, e então preencher o vetor. - Impressão: imprimir os elementos das diagonais separados por espaços, e terminar cada diagonal com uma nova linha.
- Tratamento de entradas inválidas (não exigido pelo enunciado) não será implementado para manter o código enxuto para prova.
Passo 6
Código em C (comentado). Compile por exemplo com: gcc -std=c11 -O2 diag.c -o diag
#include <stdio.h>
#include <stdlib.h>
/* Programa C: lê m, n e depois m*n inteiros (linha a linha).
Imprime a diagonal principal e a diagonal secundária. */
int main(void) {
int m, n;
if (scanf("%d %d", &m, &n) != 2) return 0;
int *A = (int*) malloc((size_t)m * n * sizeof(int));
if (!A) return 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (scanf("%d", &A[i * n + j]) != 1) {
free(A);
return 0;
}
}
}
/* Diagonal principal (0-based): A[i,i] para i = 0..min(m,n)-1 */
int p = (m < n) ? m : n;
for (int i = 0; i < p; ++i) {
if (i) printf(" ");
printf("%d", A[i * n + i]);
}
printf("\n");
/* Diagonal secundária (0-based): para cada linha i, coluna j = n-1-i */
int first = 1;
for (int i = 0; i < m; ++i) {
int j = n - 1 - i;
if (j >= 0 && j < n) {
if (!first) printf(" ");
printf("%d", A[i * n + j]);
first = 0;
}
}
printf("\n");
free(A);
return 0;
}
Passo 7
Implementação em C++ usando std::vector (mais segura e idiomática em C++):
- Vou usar um vetor de vetores: std::vector<std::vector<int>> mat(m, std::vector<int>(n)).
- Leitura com std::cin, impressão com std::cout.
- Lógica de índices é a mesma que em C (0-based).
Passo 8
Código em C++ (compile com: g++ -std=c++17 -O2 diag.cpp -o diag)
#include <bits/stdc++.h>
using namespace std;
/* Programa C++: lê m n e a matriz, imprime diagonal principal e secundária. */
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int m, n;
if (!(cin >> m >> n)) return 0;
vector<vector<int>> A(m, vector<int>(n));
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
cin >> A[i][j];
int p = min(m, n);
for (int i = 0; i < p; ++i) {
if (i) cout << ' ';
cout << A[i][i];
}
cout << '\n';
bool first = true;
for (int i = 0; i < m; ++i) {
int j = n - 1 - i;
if (j >= 0 && j < n) {
if (!first) cout << ' ';
cout << A[i][j];
first = false;
}
}
cout << '\n';
return 0;
}
Passo 9
Implementação em MATLAB/Scilab:
- Em MATLAB existe a função diag(A) que retorna a diagonal principal. Para a secundária podemos usar diag(fliplr(A)) que dá a principal da matriz invertida horizontalmente, equivalente à secundária de A.
- Em Scilab as funções correspondentes são similarmente diag() e fliplr().
- Vou dar duas versões: uma que usa as funções prontas (mais curta) e outra que faz com laço (educacional).
Passo 10
Código MATLAB (vetorizado e laço). Para rodar, crie um script ou função. Exemplo de uso: digite m, n e a matriz no workspace ou adapte a leitura conforme necessário.
% Versão vetorizada (MATLAB)
% Suponha A é uma matriz m x n já presente no workspace.
% Se quiser ler automaticamente, substitua pela leitura desejada.
% Exemplo de leitura simples:
% m = input('m = '); n = input('n = ');
% A = zeros(m,n);
% for i = 1:m
% for j = 1:n
% A(i,j) = input('');
% end
% end
% Usando diag (principal)
principal = diag(A); % retorna vetor coluna com min(m,n) elementos
% Usando fliplr + diag (secundária)
secondary = diag(fliplr(A));
% Mostrar resultados (imprime vetores linha)
fprintf('%d', principal(1));
for k = 2:length(principal)
fprintf(' %d', principal(k));
end
fprintf('\n');
if ~isempty(secondary)
fprintf('%d', secondary(1));
for k = 2:length(secondary)
fprintf(' %d', secondary(k));
end
end
fprintf('\n');
Código Scilab (muito parecido):
// Versão Scilab (assume A presente no ambiente)
principal = diag(A);
secondary = diag(fliplr(A));
// Imprime principal
if size(principal, 'r') > 0 then
mprintf('%d', principal(1));
for k = 2:size(principal, 'r')
mprintf(' %d', principal(k));
end
end
mprintf('\n');
// Imprime secundária
if size(secondary, 'r') > 0 then
mprintf('%d', secondary(1));
for k = 2:size(secondary, 'r')
mprintf(' %d', secondary(k));
end
end
mprintf('\n');
Resposta
/* C implementation */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int m, n;
if (scanf("%d %d", &m, &n) != 2) return 0;
int *A = (int*) malloc((size_t)m * n * sizeof(int));
if (!A) return 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (scanf("%d", &A[i * n + j]) != 1) {
free(A);
return 0;
}
}
}
int p = (m < n) ? m : n;
for (int i = 0; i < p; ++i) {
if (i) printf(" ");
printf("%d", A[i * n + i]);
}
printf("\n");
int first = 1;
for (int i = 0; i < m; ++i) {
int j = n - 1 - i;
if (j >= 0 && j < n) {
if (!first) printf(" ");
printf("%d", A[i * n + j]);
first = 0;
}
}
printf("\n");
free(A);
return 0;
}
// C++ implementation
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int m, n;
if (!(cin >> m >> n)) return 0;
vector<vector<int>> A(m, vector<int>(n));
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
cin >> A[i][j];
int p = min(m, n);
for (int i = 0; i < p; ++i) {
if (i) cout << ' ';
cout << A[i][i];
}
cout << '\n';
bool first = true;
for (int i = 0; i < m; ++i) {
int j = n - 1 - i;
if (j >= 0 && j < n) {
if (!first) cout << ' ';
cout << A[i][j];
first = false;
}
}
cout << '\n';
return 0;
}
% MATLAB implementation (vetorizado)
% Preencha A no workspace ou adapte a leitura.
principal = diag(A);
secondary = diag(fliplr(A));
if ~isempty(principal)
fprintf('%d', principal(1));
for k = 2:length(principal)
fprintf(' %d', principal(k));
end
end
fprintf('\n');
if ~isempty(secondary)
fprintf('%d', secondary(1));
for k = 2:length(secondary)
fprintf(' %d', secondary(k));
end
end
fprintf('\n');
// Scilab implementation
principal = diag(A);
secondary = diag(fliplr(A));
if size(principal, 'r') > 0 then
mprintf('%d', principal(1));
for k = 2:size(principal, 'r')
mprintf(' %d', principal(k));
end
end
mprintf('\n');
if size(secondary, 'r') > 0 then
mprintf('%d', secondary(1));
for k = 2:size(secondary, 'r')
mprintf(' %d', secondary(k));
end
end
mprintf('\n');