01 / 17
Lógica de Programação · Sem 12 · Dia 1 (Aulas 1 e 2)

Matrizes:
uma tabela
em memória

Do conceito de linhas e colunas ao percurso linha a linha — e o primeiro algoritmo clássico de matriz: as diagonais em Python.

ProfessorGuilherme Antunes CursoTécnico em Desenvolvimento de Sistemas Duração100 minutos (Aula 1 + Aula 2)
02 / 17
Onde estamos na unidade

Da linha ao plano

Estamos no segundo capítulo de estruturas de dados. Nas duas semanas anteriores, vimos vetores: uma fila de valores. Esta semana, damos um salto de dimensão — matrizes — e na próxima fecharemos a unidade com funções.

Semana 11 · feito

Vetores

Estrutura linear de uma dimensão. Indexação por [i], busca linear, ordenação e estatísticas.

Aqui Semana 12 · agora

Matrizes

Estrutura de duas dimensões — linhas × colunas. Indexação por [i][j], percursos e operações agregadas.

Semana 13 · próxima

Funções e procedimentos

Encapsulamento de lógica reutilizável. Parâmetros, retorno, escopo. Fecha a unidade.

03 / 17
Objetivos do Dia

Ao final, você será capaz de.

01

A1Entender por que variáveis soltas não dão conta de uma tabela 2D — e o que motiva matrizes

02

A1Declarar matrizes em Python e acessar elementos por (linha, coluna) sem cair em aliasing

03

A2Implementar o laço aninhado que percorre cada célula uma vez em ordem row-major

04

A2Resolver o desafio BeeCrowd 1534 — Array 123: marcar diagonais e tratar a sobreposição central

04 / 17
Aula 1 Ponto de partida

O problema das variáveis em grade

Você está estagiando em uma empresa de análise de imagens. A primeira tarefa: representar uma mini-imagem 3×4 onde cada pixel está ligado (1) ou apagado (0). Sem matriz, a ideia ingênua é 12 variáveis separadas.

  • Declarar p11, p12, …, p34 (12 variáveis)
  • Como ligar todos os pixels da linha 2?
  • Como contar quantos ativos cada coluna tem?
  • Como acessar rapidamente a posição (3, 2)?

Sem uma estrutura 2D, o código vira uma escada de ifs impossível de manter — e cresce N×M com o tamanho da imagem.

p11 = 0; p12 = 1; p13 = 0; p14 = 1
p21 = 1; p22 = 0; p23 = 1; p24 = 0
p31 = 0; p32 = 1; p33 = 1; p34 = 0

# "Ligar a linha 2 toda":
p21 = 1
p22 = 1
p23 = 1
p24 = 1

# "Contar ativos da coluna 1":
ativos_col1 = p11 + p21 + p31
# … e se a imagem virar 100×100?
05 / 17
Aula 1 Construindo o conceito

O que é uma matriz?

Uma matriz é uma estrutura de duas dimensões: linhas × colunas. É a generalização natural do vetor — em vez de uma fila, uma grade. Cada célula é localizada por um par de índices (i, j), onde i é a linha e j a coluna.

i=0i=1i=2
0(0,0)
1(0,1)
0(0,2)
1(0,3)
1(1,0)
0(1,1)
1(1,2)
0(1,3)
0(2,0)
1(2,1)
1(2,2)
0(2,3)
j=0j=1j=2j=3
Forma 3×4: 3 linhas, 4 colunas — total de 12 posições. Acima, a mini-imagem do estagiário: cada 1 é um pixel aceso. m[2][1] = 1 significa "linha 2, coluna 1, pixel aceso".
06 / 17
Aula 1 Indexação

Base 0 vs base 1

Antes de mexer com qualquer matriz, decida — e declare — qual base de indexação você usa. Confundir as duas é a fonte número um de bugs off-by-one.

Base 0 — Python, C, Java, JavaScript

(0,0)
(0,1)
(0,2)
(1,0)
(1,1)
(1,2)
(2,0)
(2,1)
(2,2)

Primeira linha em m[0], última em m[N-1]. É o padrão de Python — e o que usaremos no curso.

Base 1 — Excel, MATLAB, R

(1,1)
(1,2)
(1,3)
(2,1)
(2,2)
(2,3)
(3,1)
(3,2)
(3,3)

Primeira linha em m(1), última em m(N). Mais natural para humanos, mas não é o padrão da maioria das linguagens.

Regra de ouro: sempre diga, no comentário do código ou na primeira linha do pseudocódigo, qual base está usando. Em uma matriz 3×3, "linha 3" pode ser m[2] (base 0) ou m[3] (base 1) — e esse mal-entendido custa horas de depuração.
07 / 17
Aula 1 Por dentro da memória

Como a matriz vira uma fila

A memória do computador é linear — não tem "linhas" e "colunas". Quem decide a ordem é a linguagem. Em Python, C e na maioria das linguagens, vale a regra row-major: percorre a linha inteira antes de passar para a próxima.

matriz 3×4 → memória contígua na ordem (linha 0 → linha 1 → linha 2):

A(0,0)
B(0,1)
C(0,2)
D(0,3)
E(1,0)
F(1,1)
G(1,2)
H(1,3)
I(2,0)
J(2,1)
K(2,2)
L(2,3)
Por que isso importa: o processador é muito mais rápido lendo valores fisicamente próximos (cache hit). Em row-major, percorrer linha a linha respeita esse alinhamento. Percorrer coluna a coluna salta de 4 em 4 posições — funciona, mas pode ser dezenas de vezes mais lento em matrizes grandes. Em Fortran e MATLAB a regra é a oposta — column-major.
08 / 17
Aula 1 Sintaxe Python

Criando a matriz — e a armadilha do aliasing

Existem duas formas comuns de criar uma matriz 3×4 em Python. Uma é tentadora e errada; a outra é chata e correta. A diferença muda o comportamento do programa inteiro.

# ❌ ERRADO — aliasing!
m = [[0] * 4] * 3

m[0][1] = 9
print(m)
# [[0, 9, 0, 0],
#  [0, 9, 0, 0],   ← também mudou
#  [0, 9, 0, 0]]   ← também mudou

# As 3 "linhas" são, na verdade,
# 3 referências para a MESMA lista.
# Mudar uma muda todas.
# ✅ CERTO — uma linha por vez
m = [[0] * 4 for _ in range(3)]

m[0][1] = 9
print(m)
# [[0, 9, 0, 0],
#  [0, 0, 0, 0],   ← intocada
#  [0, 0, 0, 0]]   ← intocada

# A list comprehension EXECUTA
# [0]*4 três vezes, criando
# três listas independentes.
Por que acontece: o operador * em listas não copia — ele repete a mesma referência. Funciona para tipos imutáveis (int, str), mas listas são mutáveis. Para criar N linhas independentes, use sempre list comprehension.
09 / 17
Aula 2 Ponte

Já temos a grade… e agora?

Na Aula 1 aprendemos a declarar e acessar uma matriz por (i, j). Mas qualquer programa de verdade precisa visitar todas as células: imprimir a imagem, somar valores, validar regras. Esse é o problema do percurso — e a ferramenta para resolvê-lo tem nome: laço aninhado.

10 / 17
Aula 2 Construindo o conceito

O que é percorrer uma matriz?

Percorrer uma matriz é visitar cada elemento uma única vez. O padrão didático — e o mais comum em row-major — é linha a linha, da esquerda para a direita. Em uma matriz N × M, o percurso completo tem complexidade O(N · M).

ordem de visita em uma matriz 3×4:

(0,0)
(0,1)
(0,2)
(0,3)
(1,0)
(1,1)
(1,2)
(1,3)
(2,0)
10º(2,1)
11º(2,2)
12º(2,3)
Por que linha a linha: em row-major (Python, C), as células da mesma linha estão contíguas na memória. O percurso linha a linha respeita o cache do processador e é a ordem natural de impressão na tela.
11 / 17
Aula 2 O laço aninhado

Dois for, um dentro do outro

O laço externo controla a linha (i). O laço interno percorre a coluna (j). Para cada valor de i, o j varre todas as colunas — e só depois i avança.

// Pseudocódigo
para i de 0 ate n_linhas - 1 faca
    para j de 0 ate n_colunas - 1 faca
        processar( m[i][j] )
    fim_para
fim_para
# Python — imprimir a matriz
m = [[1, 2, 3, 4],
     [5, 6, 7, 8],
     [9, 0, 1, 2]]

for i in range(len(m)):           # linhas
    for j in range(len(m[i])):    # colunas
        print(m[i][j], end=' ')
    print()                       # quebra linha
A ordem importa: com i externo e j interno, percorremos linha a linha (row-major) — rápido e natural. Invertendo (j externo, i interno), percorremos coluna a coluna — funciona, mas vai contra o layout de memória do Python.
12 / 17
Aula 2 Antes do desafio

Passo a passo do Array 123

O desafio (BeeCrowd 1534): dado N, montar uma matriz N × N onde a diagonal principal vale 1, a diagonal secundária vale 2, e todos os outros valem 3. Vamos destrinchar em 5 passos antes de codar.

1

Leia N. O problema tem múltiplos casos até o fim da entrada — use while True + try / except EOFError.

2

Percorra linha a linha. for i in range(N) e inicie uma string vazia linha = "" para acumular o caractere de cada coluna.

3

Decida o caractere de cada coluna. for j in range(N) e use if / elif / else com as duas condições de diagonal.

4

Cuidado com o centro. Em N ímpar, a célula central pertence às duas diagonais — a secundária tem prioridade. Teste i + j == N - 1 ANTES de i == j.

5

Imprima. Após cada linha pronta, print(linha). Repita até o EOF.

A pegadinha do enunciado: "diagonal principal = 1, secundária = 2, demais = 3" sugere uma ordem na cabeça (1, 2, 3) — mas o código precisa testar a secundária primeiro. Lembre-se: a ordem dos if manda mais que a ordem do enunciado.
13 / 17
Aula 2 Sua vez · Desafio · Versão 1

Tentativa com bug

Um colega entregou esta versão. Roda, compila — mas falha em N ímpar. Olhe a saída para N = 3: a posição central deveria ser 2 e está vindo 1.

while True:
    try:
        N = int(input())
        for i in range(N):
            linha = ""
            for j in range(N):
                if i == j:               # ⚠ principal primeiro
                    linha += "1"
                elif i + j == N - 1:     # secundária só se sobrar
                    linha += "2"
                else:
                    linha += "3"
            print(linha)
    except EOFError:
        break
Entrada: 3

Saída obtida:
1 3 2
3 1 3        ← deveria ser 2!
2 3 1

Saída esperada:
1 3 2
3 2 3
2 3 1

# Em N=3, a célula (1,1)
# está nas DUAS diagonais
# mas o if pega a principal
# primeiro e nunca vê a 2ª.
Diagnóstico: em N = 3, a célula (1, 1) satisfaz tanto i == j (principal) quanto i + j == N - 1 (secundária = 1 + 1 == 2). O if/elif avalia em ordem — quem chega primeiro vence. Trocar a ordem das duas condições resolve.
14 / 17
Aula 2 Sua vez · Desafio · Versão 2

Versão corrigida

A única mudança em relação à versão bugada: a ordem das duas primeiras condições. A secundária vem antes. Agora o programa passa tanto para N par quanto ímpar.

while True:
    try:
        N = int(input())
        for i in range(N):
            linha = ""
            for j in range(N):
                if i + j == N - 1:       # ✅ secundária PRIMEIRO
                    linha += "2"
                elif i == j:             # principal depois
                    linha += "1"
                else:
                    linha += "3"
            print(linha)
    except EOFError:
        break
Entrada:
3
4

Saída:
1 3 2
3 2 3
2 3 1

1 3 3 2
3 1 2 3
3 2 1 3
2 3 3 1

── teste com N=1, N=2,
── N=3, N=4 — todos passam
Regras do desafio: implemente na mão, sem usar bibliotecas tipo numpy. Cada linha deve ser impressa sem espaços entre os números (no enunciado original do BeeCrowd). Teste com N = 1, 2, 3, 4, 5 — preste atenção em N ímpar.
15 / 17
Pause e responda

O que é uma matriz, afinal?

Uma matriz é uma estrutura de dados organizada em duas dimensões. Qual das alternativas abaixo a descreve corretamente?

AUm único valor armazenado em uma variável
BUm conjunto de funções organizadas em sequência
CUma lista linear de valores acessada por um único índice
DUma estrutura com várias posições organizadas em linhas e colunas
Por que D: a matriz é justamente a extensão do vetor para duas dimensões. Linhas e colunas são os dois eixos, e cada célula é localizada por um par (i, j) — daí o acesso m[i][j]. A alternativa C descreve um vetor, não uma matriz.
16 / 17
Então ficamos assim…

O que aprendemos hoje

  • Matriz → estrutura 2D em linhas × colunas; cada célula localizada por (i, j), acessada com m[i][j]
  • Base 0 em Python — primeira linha em m[0], primeira coluna em m[i][0]
  • Row-major — a matriz vira fila na memória linha a linha; percorrer nessa ordem respeita o cache
  • Aliasing — nunca declare matriz com [[0]*M]*N; use list comprehension [[0]*M for _ in range(N)]
  • Laço aninhadoi externo (linha), j interno (coluna); percurso completo é O(N · M)
  • Array 123 — em matrizes ímpares, a diagonal secundária precisa ser testada antes da principal
Próxima aula · Dia 2

Operações agregadas + Jogo da Velha — soma por linha, soma por coluna, média geral, e modelagem de jogos com matrizes. Fecharemos a semana com um Jogo da Velha completo em terminal.

17 / 17
Referências

De onde veio cada coisa

BEECROWD. Problema 1534 — Array 123. BeeCrowd Online Judge, [s.d.]. Disponível em: beecrowd.com.br/judge/pt/problems/view/1534. Acesso em: 20 mai. 2026.

PYTHON SOFTWARE FOUNDATION. Data Structures — Nested List Comprehensions. The Python Tutorial, [s.d.]. Disponível em: docs.python.org/3/tutorial/datastructures.html. Acesso em: 20 mai. 2026.

FAQ Python. Why does a list multiplied by a number return repeated references? docs.python.org, [s.d.]. Disponível em: docs.python.org/3/faq/programming.html. Acesso em: 20 mai. 2026.

Base institucional: SEDUC-SP. Educação Profissional Paulista — Técnico em Desenvolvimento de Sistemas. Componente 1, Unidade 4, Semana 12 (SISANO1C1B2S12A1 e SISANO1C1B2S12A2).

Identidade visual · adaptação para apresentação HTML por Guilherme Antunes