· Andrea Pollini · programmazione · 28 min read

Esercizi sulle matrici in C++ assegnati al polimi

Una raccolta di esercizi sulle matrici in C++ assegnati al polimi per aiutarti a consolidare le tue conoscenze e a prepararti per gli esami di informatica.

Una raccolta di esercizi sulle matrici in C++ assegnati al polimi per aiutarti a consolidare le tue conoscenze e a prepararti per gli esami di informatica.

In questo articolo troverai una serie di esercizi sulle matrici in C++ assegnati al Politecnico di Milano per aiutarti a consolidare le tue conoscenze e a prepararti per gli esami di informatica.

Reference:

Esercizio 1

Scrivere un programma che chiede all’utente di riempire una matrice, la stampa, cerca, se esiste, la prima occorrenza dello 0 e dice in che posizione è stata trovata

Soluzione (con std::vector)

Prima di tutto, per risolvere questo esercizio, dobbiamo capire alcuni concetti di base.

Una matrice è essenzialmente un array bidimensionale di elementi. In C++, possiamo rappresentare una matrice utilizzando un array bidimensionale o un vettore di vettori.

Per riempire una matrice, chiederemo all’utente di inserire i valori degli elementi uno per uno.

Successivamente, dovremo scorrere la matrice per cercare la prima occorrenza dello 0 e memorizzare la sua posizione.

Una volta trovato lo 0, stampiamo la sua posizione.

Ora passiamo al codice:

#include <iostream>
#include <vector>

using namespace std;

// Funzione per riempire la matrice
void riempiMatrice(vector<vector<int>>& matrice, int righe, int colonne) {
    cout << "Inserisci gli elementi della matrice:" << endl;
    for (int i = 0; i < righe; ++i) {
        for (int j = 0; j < colonne; ++j) {
            cin >> matrice[i][j];
        }
    }
}

// Funzione per stampare la matrice
void stampaMatrice(const vector<vector<int>>& matrice, int righe, int colonne) {
    cout << "La matrice inserita è:" << endl;
    for (int i = 0; i < righe; ++i) {
        for (int j = 0; j < colonne; ++j) {
            cout << matrice[i][j] << " ";
        }
        cout << endl;
    }
}

// Funzione per cercare la prima occorrenza dello 0 e restituire la sua posizione
pair<int, int> trovaPrimoZero(const vector<vector<int>>& matrice, int righe, int colonne) {
    for (int i = 0; i < righe; ++i) {
        for (int j = 0; j < colonne; ++j) {
            if (matrice[i][j] == 0) {
                return make_pair(i, j);
            }
        }
    }
    return make_pair(-1, -1); // Ritorna -1, -1 se lo zero non viene trovato
}

int main() {
    int righe, colonne;
    cout << "Inserisci il numero di righe della matrice: ";
    cin >> righe;
    cout << "Inserisci il numero di colonne della matrice: ";
    cin >> colonne;

    // Dichiarazione e allocazione della matrice
    vector<vector<int>> matrice(righe, vector<int>(colonne));

    // Riempimento della matrice
    riempiMatrice(matrice, righe, colonne);

    // Stampare la matrice
    stampaMatrice(matrice, righe, colonne);

    // Trovare la posizione del primo zero
    pair<int, int> posizioneZero = trovaPrimoZero(matrice, righe, colonne);

    // Verifica se lo zero è stato trovato
    if (posizioneZero.first != -1 && posizioneZero.second != -1) {
        cout << "Il primo zero si trova alla riga " << posizioneZero.first << " e alla colonna " << posizioneZero.second << endl;
    } else {
        cout << "Nessun zero trovato nella matrice." << endl;
    }

    return 0;
}

Nel codice sopra:

  1. Abbiamo dichiarato tre funzioni: riempiMatrice per riempire la matrice, stampaMatrice per stampare la matrice e trovaPrimoZero per cercare la prima occorrenza dello 0.
  2. Nella funzione main, chiediamo all’utente il numero di righe e colonne della matrice, quindi allochiamo spazio per la matrice.
  3. Chiamiamo le funzioni per riempire, stampare la matrice e trovare la posizione del primo zero.
  4. Infine, stampiamo la posizione del primo zero se viene trovato, altrimenti segnaliamo che non è stato trovato alcuno zero.

Soluzione (con array bidimensionale)

Possiamo risolvere l’esercizio senza utilizzare std::vector, utilizzando invece gli array bidimensionali tradizionali in C++.

Ecco il codice modificato:

#include <iostream>

using namespace std;

const int MAX_RIGHE = 100;
const int MAX_COLONNE = 100;

// Funzione per riempire la matrice
void riempiMatrice(int matrice[][MAX_COLONNE], int righe, int colonne) {
    cout << "Inserisci gli elementi della matrice:" << endl;
    for (int i = 0; i < righe; ++i) {
        for (int j = 0; j < colonne; ++j) {
            cin >> matrice[i][j];
        }
    }
}

// Funzione per stampare la matrice
void stampaMatrice(int matrice[][MAX_COLONNE], int righe, int colonne) {
    cout << "La matrice inserita è:" << endl;
    for (int i = 0; i < righe; ++i) {
        for (int j = 0; j < colonne; ++j) {
            cout << matrice[i][j] << " ";
        }
        cout << endl;
    }
}

// Funzione per cercare la prima occorrenza dello 0 e restituire la sua posizione
pair<int, int> trovaPrimoZero(int matrice[][MAX_COLONNE], int righe, int colonne) {
    for (int i = 0; i < righe; ++i) {
        for (int j = 0; j < colonne; ++j) {
            if (matrice[i][j] == 0) {
                return make_pair(i, j);
            }
        }
    }
    return make_pair(-1, -1); // Ritorna -1, -1 se lo zero non viene trovato
}

int main() {
    int righe, colonne;
    cout << "Inserisci il numero di righe della matrice: ";
    cin >> righe;
    cout << "Inserisci il numero di colonne della matrice: ";
    cin >> colonne;

    // Dichiarazione della matrice
    int matrice[MAX_RIGHE][MAX_COLONNE];

    // Riempimento della matrice
    riempiMatrice(matrice, righe, colonne);

    // Stampare la matrice
    stampaMatrice(matrice, righe, colonne);

    // Trovare la posizione del primo zero
    pair<int, int> posizioneZero = trovaPrimoZero(matrice, righe, colonne);

    // Verifica se lo zero è stato trovato
    if (posizioneZero.first != -1 && posizioneZero.second != -1) {
        cout << "Il primo zero si trova alla riga " << posizioneZero.first << " e alla colonna " << posizioneZero.second << endl;
    } else {
        cout << "Nessun zero trovato nella matrice." << endl;
    }

    return 0;
}

In questo codice:

  • Utilizziamo array bidimensionali int matrice[MAX_RIGHE][MAX_COLONNE] per rappresentare la matrice.
  • Le funzioni riempiMatrice, stampaMatrice e trovaPrimoZero sono modificate di conseguenza per accettare e manipolare array bidimensionali.
  • Le costanti MAX_RIGHE e MAX_COLONNE sono definite per limitare le dimensioni massime della matrice.

Esercizio 2

Scrivere un programma che chiede all’utente di riempire una matrice, la stampa, cerca, se esiste, la prima occorrenza dello 0, l’ultima occorrenza dello 0 e l’occorrenza dello 0 in posizione mediana e dice in che posizione sono state trovate .

Soluzione

Prima di tutto, per risolvere questo esercizio, dobbiamo comprendere alcuni concetti di base.

Teoria

  1. Matrice: Una matrice è una struttura dati bidimensionale composta da righe e colonne. Ogni elemento della matrice è accessibile tramite le sue coordinate di riga e colonna.
  2. Riempimento della Matrice: Chiederemo all’utente di inserire i valori nella matrice. Utilizzeremo un doppio ciclo for per scorrere ogni elemento della matrice e chiedere all’utente di inserire il valore.
  3. Stampa della Matrice: Dovremo stampare la matrice dopo che l’utente l’ha riempita. Ancora una volta, useremo un doppio ciclo for per attraversare ogni elemento della matrice e stamparlo.
  4. Ricerca delle occorrenze dello 0:
    • Prima occorrenza dello 0: Scorreremo la matrice finché non troviamo il primo 0 e memorizzeremo le sue coordinate.
    • Ultima occorrenza dello 0: Scorreremo la matrice all’indietro partendo dall’ultimo elemento e troveremo l’ultima occorrenza dello 0.
    • Occorrenza dello 0 in posizione mediana: Per trovare la posizione mediana dello 0, divideremo la matrice in due parti uguali e cercheremo la prima occorrenza dello 0 nella parte centrale della matrice.

Codice in C++

#include <iostream>
#include <vector>

using namespace std;

// Funzione per riempire la matrice
void riempiMatrice(vector<vector<int>>& matrice) {
    int righe, colonne;
    cout << "Inserisci il numero di righe della matrice: ";
    cin >> righe;
    cout << "Inserisci il numero di colonne della matrice: ";
    cin >> colonne;
    
    matrice.resize(righe, vector<int>(colonne)); // Ridimensiona la matrice
    cout << "Inserisci gli elementi della matrice:\n";
    for (int i = 0; i < righe; ++i) {
        for (int j = 0; j < colonne; ++j) {
            cin >> matrice[i][j]; // Inserisce l'elemento nella matrice
        }
    }
}

// Funzione per stampare la matrice
void stampaMatrice(const vector<vector<int>>& matrice) {
    cout << "La matrice inserita è:\n";
    for (const auto& riga : matrice) {
        for (int elemento : riga) {
            cout << elemento << " ";
        }
        cout << endl;
    }
}

// Funzione per trovare la prima occorrenza dello 0
pair<int, int> trovaPrimoZero(const vector<vector<int>>& matrice) {
    int righe = matrice.size();
    int colonne = matrice[0].size();
    for (int i = 0; i < righe; ++i) {
        for (int j = 0; j < colonne; ++j) {
            if (matrice[i][j] == 0) {
                return make_pair(i, j);
            }
        }
    }
    return make_pair(-1, -1); // Se non viene trovato nessuno zero
}

// Funzione per trovare l'ultima occorrenza dello 0
pair<int, int> trovaUltimoZero(const vector<vector<int>>& matrice) {
    int righe = matrice.size();
    int colonne = matrice[0].size();
    for (int i = righe - 1; i >= 0; --i) {
        for (int j = colonne - 1; j >= 0; --j) {
            if (matrice[i][j] == 0) {
                return make_pair(i, j);
            }
        }
    }
    return make_pair(-1, -1); // Se non viene trovato nessuno zero
}

// Funzione per trovare l'occorrenza dello 0 nella posizione mediana
pair<int, int> trovaZeroPosizioneMediana(const vector<vector<int>>& matrice) {
    int righe = matrice.size();
    int colonne = matrice[0].size();
    int rigaMediana = righe / 2;
    int colonnaMediana = colonne / 2;
    for (int i = rigaMediana; i >= 0 && i <= rigaMediana + 1; ++i) {
        for (int j = colonnaMediana; j >= 0 && j <= colonnaMediana + 1; ++j) {
            if (matrice[i][j] == 0) {
                return make_pair(i, j);
            }
        }
    }
    return make_pair(-1, -1); // Se non viene trovato nessuno zero
}

int main() {
    vector<vector<int>> matrice;
    riempiMatrice(matrice);
    stampaMatrice(matrice);

    pair<int, int> primoZero = trovaPrimoZero(matrice);
    if (primoZero.first != -1) {
        cout << "La prima occorrenza dello 0 è alla posizione: (" << primoZero.first << ", " << primoZero.second << ")\n";
    } else {
        cout << "Nessuna occorrenza dello 0 trovata.\n";
    }

    pair<int, int> ultimoZero = trovaUltimoZero(matrice);
    if (ultimoZero.first != -1) {
        cout << "L'ultima occorrenza dello 0 è alla posizione: (" << ultimoZero.first << ", " << ultimoZero.second << ")\n";
    } else {
        cout << "Nessuna occorrenza dello 0 trovata.\n";
    }

    pair<int, int> zeroPosizioneMediana = trovaZeroPosizioneMediana(matrice);
    if (zeroPosizioneMediana.first != -1) {
        cout << "L'occorrenza dello 0 nella posizione mediana è alla posizione: (" << zeroPosizioneMediana.first << ", " << zeroPosizioneMediana.second << ")\n";
    } else {
        cout << "Nessuna occorrenza dello 0 trovata nella posizione mediana.\n";
    }

    return 0;
}

Questo programma chiede all’utente di inserire il numero di righe e colonne per la matrice, quindi chiede di riempire la matrice con valori interi. Dopo aver stampato la matrice, trova e stampa la posizione della prima occorrenza dello 0, dell’ultima occorrenza dello 0 e dell’occorren

Esercizio 3

Scrivere un programma che riempia una matrice 20x30 chiedendo all’utente di inserire gli elementi, ma inserendo nella matrice solo gli elementi pari.

Il programma termina quando la matrice è piena.

Soluzione

Il programma richiede di riempire una matrice 20x30 con elementi pari inseriti dall’utente, e termina quando la matrice è piena.

Per farlo, possiamo utilizzare un array bidimensionale (matrice) per memorizzare gli elementi, un ciclo per chiedere all’utente di inserire i valori e un’altra struttura di controllo per verificare se il valore inserito è pari o meno.

In C++, possiamo rappresentare una matrice utilizzando un array bidimensionale. La struttura di controllo più semplice per determinare se un numero è pari è l’operatore modulo (%), che restituisce il resto della divisione. Se il resto è zero, allora il numero è pari.

Ecco un esempio di codice che implementa questa logica:

#include <iostream>

using namespace std;

const int ROWS = 20;
const int COLS = 30;

int main() {
    int matrix[ROWS][COLS];
    int count = 0; // Contatore degli elementi inseriti

    cout << "Inserisci gli elementi pari nella matrice 20x30:" << endl;

    // Ciclo per inserire gli elementi
    for (int i = 0; i < ROWS; ++i) {
        for (int j = 0; j < COLS; ++j) {
            int num;
            cout << "Inserisci un numero pari: ";
            cin >> num;

            // Verifica se il numero è pari
            if (num % 2 == 0) {
                matrix[i][j] = num;
                count++;

                // Verifica se la matrice è piena
                if (count == ROWS * COLS) {
                    cout << "Matrice piena. Termine del programma." << endl;
                    return 0;
                }
            } else {
                cout << "Il numero inserito non è pari. Riprova." << endl;
                j--; // Permette di ripetere l'inserimento nella stessa posizione
            }
        }
    }

    return 0;
}

Spieghiamo il codice:

  1. Definiamo una matrice 20x30 matrix.
  2. Utilizziamo due cicli annidati per scorrere attraverso ogni elemento della matrice.
  3. All’interno del ciclo, chiediamo all’utente di inserire un numero.
  4. Verifichiamo se il numero inserito è pari utilizzando l’operatore modulo (%).
  5. Se è pari, lo inseriamo nella matrice e incrementiamo il contatore count.
  6. Controlliamo se la matrice è piena. Se lo è, terminiamo il programma.
  7. Se il numero inserito non è pari, avvisiamo l’utente e chiediamo di inserirne un altro nella stessa posizione.

Con questo codice, l’utente può riempire una matrice 20x30 inserendo solo numeri pari, e il programma terminerà quando la matrice sarà piena.

Esercizio 4

Scrivere un programma C++ che legge una sequenza di numeri interi e li mette nella prima riga della matrice M. La lettura della sequenza termina quando alla prima riga della matrice M sono stati assegnati 50 interi oppure quando viene letto il secondo numero intero negativo.

Soluzione

Per risolvere questo esercizio, dovremo scrivere un programma in C++ che legga una sequenza di numeri interi e li inserisca nella prima riga di una matrice M. La lettura della sequenza si interromperà quando alla prima riga della matrice M saranno stati assegnati 50 interi oppure quando viene letto il secondo numero intero negativo.

Teoria

  1. Input dei numeri: Utilizzeremo un loop per leggere i numeri interi uno alla volta dall’input dell’utente.

  2. Inserimento nella matrice: Man mano che leggiamo i numeri, li inseriremo nella prima riga della matrice.

  3. Condizioni di terminazione: Il programma terminerà quando alla prima riga della matrice sono stati assegnati 50 interi oppure quando viene letto il secondo numero intero negativo.

Codice C++

#include <iostream>
#include <vector>

using namespace std;

int main() {
    const int ROW = 1; // Numero di righe della matrice
    const int COL = 50; // Numero massimo di colonne della matrice

    // Creazione della matrice
    vector<vector<int>> M(ROW, vector<int>(COL));

    int num, count = 0;
    bool second_negative = false;

    cout << "Inserisci una sequenza di numeri interi: " << endl;

    // Lettura dei numeri interi e inserimento nella prima riga della matrice
    for (int i = 0; i < COL; ++i) {
        cin >> num;

        // Controllo se il numero è negativo
        if (num < 0) {
            if (second_negative) // Se è il secondo negativo, termina il loop
                break;
            else
                second_negative = true; // Segna che abbiamo incontrato il primo negativo
        }

        M[0][i] = num; // Inserisce il numero nella matrice
        count++; // Incrementa il contatore dei numeri inseriti

        if (count == COL || second_negative) // Se abbiamo inserito 50 numeri o trovato il secondo negativo, termina il loop
            break;
    }

    // Stampa della matrice
    cout << "La matrice M è:" << endl;
    for (int i = 0; i < ROW; ++i) {
        for (int j = 0; j < COL; ++j) {
            cout << M[i][j] << " ";
        }
        cout << endl;
    }

    return 0;
}

Spiegazione del Codice

  1. Dichiarazione della matrice: Viene creata una matrice M con una sola riga (ROW = 1) e massimo 50 colonne (COL = 50).

  2. Lettura e inserimento dei numeri: Utilizzando un loop, leggiamo i numeri interi uno alla volta e li inseriamo nella prima riga della matrice.

  3. Condizioni di terminazione: Il loop termina quando abbiamo letto 50 numeri oppure quando troviamo il secondo numero intero negativo.

  4. Stampa della matrice: Alla fine, stampiamo la matrice M per visualizzare i numeri inseriti.

Esercizio 5

Scrivere un programma che chiede all’utente di inserire una matrice 20x30, poi (dopo aver terminato la fase di inserimento) copia gli elementi dispari in una seconda matrice 20x30 senza lasciare buchi, se non in fondo.

Gli elementi in fondo (i “buchi”) siano messi a zero.

Soluzione

Teoria:

  1. Matrici: Una matrice è una collezione di elementi disposti in righe e colonne. In questo caso, abbiamo una matrice 20x30, il che significa che ha 20 righe e 30 colonne.

  2. Numeri dispari: Gli elementi dispari sono quelli che non sono divisibili per 2. Ad esempio, 1, 3, 5, ecc.

  3. Copia degli elementi dispari: Dobbiamo iterare attraverso ogni elemento della matrice inserita dall’utente e copiare gli elementi dispari in una nuova matrice, assicurandoci che non ci siano buchi nella nuova matrice, ovvero che gli elementi dispari siano inseriti consecutivamente senza spazi vuoti.

  4. Gestione dei buchi: Gli “buchi” corrispondono agli elementi della nuova matrice che non sono stati riempiti con numeri dispari. Questi buchi devono essere impostati a zero.

Codice in C++:

#include <iostream>

using namespace std;

const int ROWS = 20;
const int COLS = 30;

// Funzione per copiare gli elementi dispari dalla matrice originale alla matrice di destinazione
void copyOddNumbers(int original[][COLS], int destination[][COLS]) {
    int destRow = 0;
    int destCol = 0;

    // Itera attraverso ogni elemento della matrice originale
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            // Se l'elemento è dispari, copialo nella matrice di destinazione
            if (original[i][j] % 2 != 0) {
                destination[destRow][destCol] = original[i][j];
                destCol++;

                // Se siamo arrivati all'ultima colonna, passa alla prossima riga
                if (destCol == COLS) {
                    destRow++;
                    destCol = 0;
                }
            }
        }
    }

    // Imposta a zero eventuali buchi nella matrice di destinazione
    while (destRow < ROWS) {
        while (destCol < COLS) {
            destination[destRow][destCol] = 0;
            destCol++;
        }
        destRow++;
        destCol = 0;
    }
}

int main() {
    int originalMatrix[ROWS][COLS];
    int oddNumbersMatrix[ROWS][COLS] = {0}; // Inizializza tutti gli elementi a zero

    // Input della matrice dall'utente
    cout << "Inserisci gli elementi della matrice 20x30:\n";
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            cin >> originalMatrix[i][j];
        }
    }

    // Copia degli elementi dispari nella nuova matrice
    copyOddNumbers(originalMatrix, oddNumbersMatrix);

    // Stampare la nuova matrice
    cout << "Matrice con solo numeri dispari:\n";
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            cout << oddNumbersMatrix[i][j] << " ";
        }
        cout << endl;
    }

    return 0;
}

In questo programma, abbiamo una funzione copyOddNumbers che prende la matrice originale e la matrice di destinazione come argomenti e copia gli elementi dispari dalla matrice originale alla matrice di destinazione, garantendo che non ci siano buchi. Infine, nella funzione main, chiediamo all’utente di inserire gli elementi della matrice originale, quindi chiamiamo la funzione copyOddNumbers per ottenere la nuova matrice con solo numeri dispari, che stampiamo a schermo.

Esercizio 6

Scrivere un programma che chiede all’utente di inserire una matrice NxN con elementi tutti diversi. Se l’utente inserisce un numero già inserito il programma lo avvisa dell’errore e chiede nuovamente di inserire l’elemento.

Soluzione

Teoria:

Questo esercizio richiede di scrivere un programma C++ che permetta all’utente di inserire una matrice quadrata N×NN \times N con elementi tutti diversi. Se l’utente inserisce un numero già presente nella matrice, il programma deve segnalare l’errore e chiedere nuovamente di inserire l’elemento.

Per risolvere questo problema, possiamo utilizzare un array bidimensionale per rappresentare la matrice e un insieme (o array) per tenere traccia dei numeri già inseriti. Quando l’utente inserisce un nuovo elemento, verifichiamo se è già presente nell’insieme dei numeri inseriti. Se lo è, segnaliamo l’errore e chiediamo nuovamente l’input. Altrimenti, inseriamo il numero nella matrice e nell’insieme dei numeri inseriti.

Codice in C++:

#include <iostream>
#include <unordered_set>

using namespace std;

const int MAX_SIZE = 10; // Definiamo la dimensione massima della matrice

int main() {
    int N;
    cout << "Inserisci la dimensione della matrice (N x N): ";
    cin >> N;

    if (N <= 0 || N > MAX_SIZE) {
        cout << "Dimensione non valida. La dimensione deve essere compresa tra 1 e " << MAX_SIZE << endl;
        return 1;
    }

    int matrix[MAX_SIZE][MAX_SIZE]; // Matrice per contenere gli elementi
    unordered_set<int> numbers; // Insieme per tenere traccia dei numeri inseriti

    cout << "Inserisci gli elementi della matrice:" << endl;

    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            int num;
            cout << "Elemento [" << i << "][" << j << "]: ";
            cin >> num;

            // Verifica se il numero è già stato inserito
            if (numbers.count(num) > 0) {
                cout << "Numero già inserito. Inserisci un numero diverso." << endl;
                --j; // Per consentire all'utente di reinserire il numero nella stessa posizione
                continue;
            }

            matrix[i][j] = num;
            numbers.insert(num);
        }
    }

    // Stampiamo la matrice
    cout << "Matrice inserita:" << endl;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            cout << matrix[i][j] << "\t";
        }
        cout << endl;
    }

    return 0;
}

In questo codice, inizializziamo una matrice bidimensionale matrix per contenere gli elementi della matrice e un set numbers per tenere traccia dei numeri già inseriti. Utilizziamo un doppio ciclo for per permettere all’utente di inserire gli elementi della matrice uno alla volta. Ogni volta che l’utente inserisce un numero, verifichiamo se è già presente nell’insieme numbers. Se lo è, stampiamo un messaggio di errore e chiediamo nuovamente all’utente di inserire un numero diverso. Una volta che tutti gli elementi sono stati inseriti correttamente, stampiamo la matrice risultante.

Esercizio 7

Una matrice quadrata Mat di dimensioni NxN (con N costante predefinita) è diagonalmente dominante se la somma dei valori assoluti degli elementi su ciascuna riga, escluso l’elemento sulla diagonale principale, è minore del valore assoluto dell’elemento corrispondente sulla diagonale principale.

Scrivere un programma che chiede all’utente di inserire i valori di una matrice e stampa «Dominante» se la matrice è diagonalmente dominante, «Non dominante» altrimenti.

Si ricorda che la funzione int abs(int n) restituisce il valore assoluto dell’intero n ricevuto come parametro.

Soluzione

Per risolvere questo esercizio, prima di tutto dobbiamo capire cosa significa che una matrice è diagonalmente dominante. Una matrice quadrata N×NN \times N, rappresentata come MatMat, è definita diagonalmente dominante se per ogni riga della matrice, la somma dei valori assoluti di tutti gli elementi nella riga, escluso l’elemento sulla diagonale principale, è minore del valore assoluto dell’elemento sulla diagonale principale.

In altre parole, data una matrice MatMat di dimensioni N×NN \times N, dobbiamo verificare se per ogni riga ii, la seguente condizione è soddisfatta:

j=1jiNMatij<Matii\sum_{j=1 \\ j \neq i}^{N} |Mat_{ij}| < |Mat_{ii}|

Dove MatijMat_{ij} è l’elemento della riga ii e colonna jj della matrice MatMat.

Ora passiamo alla scrittura del codice in C++.

#include <iostream>
#include <vector>
#include <cmath>

const int N = 3; // Costante predefinita per la dimensione della matrice, assumiamo qui che sia 3, ma può essere modificata a piacere.

// Funzione per verificare se la matrice è diagonalmente dominante
bool isDiagonallyDominant(const std::vector<std::vector<int>>& matrix) {
    for (int i = 0; i < N; ++i) {
        int sum = 0;
        for (int j = 0; j < N; ++j) {
            if (i != j) {
                sum += std::abs(matrix[i][j]);
            }
        }
        if (std::abs(matrix[i][i]) <= sum) {
            return false; // Non è diagonalmente dominante
        }
    }
    return true; // È diagonalmente dominante
}

int main() {
    std::vector<std::vector<int>> matrix(N, std::vector<int>(N));

    // Input della matrice dall'utente
    std::cout << "Inserisci i valori della matrice " << N << "x" << N << ":\n";
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            std::cin >> matrix[i][j];
        }
    }

    // Verifica se la matrice è diagonalmente dominante e stampa il risultato
    if (isDiagonallyDominant(matrix)) {
        std::cout << "Dominante\n";
    } else {
        std::cout << "Non dominante\n";
    }

    return 0;
}

In questo codice, abbiamo una funzione isDiagonallyDominant che prende la matrice come argomento e verifica se è diagonalmente dominante secondo la definizione data sopra. Iteriamo attraverso ogni riga della matrice, calcoliamo la somma degli elementi assoluti nella riga escludendo l’elemento sulla diagonale principale e confrontiamo questa somma con l’elemento sulla diagonale principale. Se la condizione è verificata per ogni riga, allora la matrice è diagonalmente dominante e restituiamo true, altrimenti restituiamo false.

Nel main, chiediamo all’utente di inserire i valori della matrice e poi chiamiamo la funzione isDiagonallyDominant per verificare se la matrice è diagonalmente dominante e stampiamo il risultato appropriato.

Esercizio 8

Considerata una matrice A di N x M interi, definiamo claque una sottomatrice 2 x 2 in cui la somma algebrica dei valori di una diagonale sia pari a quella dell’altra diagonale. In figura sono evidenziate le claque.

Si scriva un programma che acquisisce una matrice N x M stampa il numero di claque della matrice.

Soluzione

Per risolvere questo problema, è necessario contare quante sottomatrici 2x2 della matrice soddisfano la condizione di essere una “claque”. Una sottomatrice 2x2 è una claque se la somma degli elementi sulla diagonale principale è uguale alla somma degli elementi sulla diagonale secondaria.

Teoria

Per contare le claque, dobbiamo scorrere la matrice e per ogni possibile sottomatrice 2x2, verificare se soddisfa la condizione. La somma degli elementi di una diagonale è data dalla somma degli elementi negli angoli opposti. Quindi, per una sottomatrice 2x2 con elementi A, B, C, D, la somma degli elementi sulla diagonale principale è A + D e la somma degli elementi sulla diagonale secondaria è B + C. Quindi, una claque soddisfa la condizione se A + D = B + C.

Codice in C++

#include <iostream>
#include <vector>

using namespace std;

// Funzione per contare il numero di claque in una matrice
int countClaques(vector<vector<int>>& matrix) {
    int rows = matrix.size();
    if (rows < 2) return 0; // Non ci sono claque in una matrice con meno di due righe
    int cols = matrix[0].size();
    if (cols < 2) return 0; // Non ci sono claque in una matrice con meno di due colonne
    
    int claqueCount = 0;
    
    // Scorrere la matrice escludendo l'ultima riga e l'ultima colonna
    for (int i = 0; i < rows - 1; ++i) {
        for (int j = 0; j < cols - 1; ++j) {
            // Calcolare le somme degli elementi delle due diagonali
            int diagonal1Sum = matrix[i][j] + matrix[i+1][j+1];
            int diagonal2Sum = matrix[i][j+1] + matrix[i+1][j];
            // Verificare se le somme sono uguali, in tal caso incrementare il conteggio delle claque
            if (diagonal1Sum == diagonal2Sum) {
                claqueCount++;
            }
        }
    }
    
    return claqueCount;
}

int main() {
    int N, M;
    cout << "Inserisci il numero di righe della matrice: ";
    cin >> N;
    cout << "Inserisci il numero di colonne della matrice: ";
    cin >> M;
    
    vector<vector<int>> matrix(N, vector<int>(M));
    
    cout << "Inserisci gli elementi della matrice:" << endl;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            cin >> matrix[i][j];
        }
    }
    
    int claqueCount = countClaques(matrix);
    
    cout << "Il numero di claque nella matrice è: " << claqueCount << endl;
    
    return 0;
}

Spiegazione del Codice

  1. La funzione countClaques prende in input una matrice di interi e restituisce il numero di claque nella matrice.
  2. Scandisce la matrice escludendo l’ultima riga e l’ultima colonna perché non si possono formare claque con esse.
  3. Per ogni sottomatrice 2x2, calcola le somme degli elementi delle due diagonali e le confronta. Se le somme sono uguali, incrementa il conteggio delle claque.
  4. La funzione restituisce il conteggio finale delle claque.
  5. Nel main, l’utente inserisce le dimensioni e gli elementi della matrice, quindi viene chiamata la funzione countClaques per calcolare il numero di claque nella matrice e stamparlo a schermo.

Esercizio 9

Si scriva un programma che chiede all’utente di riempire una matrice NxN (con N costante globale predefinita) di interi e stampa la lunghezza della sequenza più lunga orizzontale, verticale o diagonale di numeri uguali consecutivi.

Soluzione

Teoria

  1. Matrice NxN: Una matrice NxN è una struttura dati bidimensionale che ha N righe e N colonne, dove ogni elemento è identificato da una coppia di indici (riga, colonna).

  2. Sequenza consecutiva: Una sequenza di numeri consecutivi è una serie di numeri che seguono uno dopo l’altro senza interruzioni. Ad esempio, 3 è una sequenza consecutiva di lunghezza 3.

  3. Lunghezza della sequenza più lunga: In una matrice, dobbiamo trovare la lunghezza massima di una sequenza consecutiva di numeri uguali in qualsiasi direzione: orizzontale, verticale o diagonale.

Codice in C++

#include <iostream>
using namespace std;

const int N = 3; // Dimensione della matrice, puoi cambiarla a tuo piacimento

// Funzione per trovare la lunghezza della sequenza più lunga
int lunghezzaSequenzaPiuLunga(int matrice[N][N]) {
    int lunghezzaMassima = 0;

    // Scansione orizzontale
    for (int riga = 0; riga < N; riga++) {
        int contatore = 1;
        for (int colonna = 1; colonna < N; colonna++) {
            if (matrice[riga][colonna] == matrice[riga][colonna - 1]) {
                contatore++;
            } else {
                contatore = 1; // Resetta il contatore se il numero non è consecutivo
            }
            if (contatore > lunghezzaMassima) {
                lunghezzaMassima = contatore;
            }
        }
    }

    // Scansione verticale
    for (int colonna = 0; colonna < N; colonna++) {
        int contatore = 1;
        for (int riga = 1; riga < N; riga++) {
            if (matrice[riga][colonna] == matrice[riga - 1][colonna]) {
                contatore++;
            } else {
                contatore = 1; // Resetta il contatore se il numero non è consecutivo
            }
            if (contatore > lunghezzaMassima) {
                lunghezzaMassima = contatore;
            }
        }
    }

    // Scansione diagonale (dal basso verso l'alto)
    for (int i = 0; i < N; i++) {
        int contatore = 1;
        for (int riga = N - 2, colonna = i + 1; riga >= 0 && colonna < N; riga--, colonna++) {
            if (matrice[riga][colonna] == matrice[riga + 1][colonna - 1]) {
                contatore++;
            } else {
                contatore = 1; // Resetta il contatore se il numero non è consecutivo
            }
            if (contatore > lunghezzaMassima) {
                lunghezzaMassima = contatore;
            }
        }
    }

    // Scansione diagonale (dall'alto verso il basso)
    for (int i = 1; i < N; i++) {
        int contatore = 1;
        for (int riga = i + 1, colonna = N - 2; riga < N && colonna >= 0; riga++, colonna--) {
            if (matrice[riga][colonna] == matrice[riga - 1][colonna + 1]) {
                contatore++;
            } else {
                contatore = 1; // Resetta il contatore se il numero non è consecutivo
            }
            if (contatore > lunghezzaMassima) {
                lunghezzaMassima = contatore;
            }
        }
    }

    return lunghezzaMassima;
}

int main() {
    int matrice[N][N];

    // Input della matrice dall'utente
    cout << "Inserisci gli elementi della matrice " << N << "x" << N << ":\n";
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> matrice[i][j];
        }
    }

    // Trova e stampa la lunghezza della sequenza più lunga
    int lunghezza = lunghezzaSequenzaPiuLunga(matrice);
    cout << "La lunghezza della sequenza piu' lunga di numeri uguali consecutivi e': " << lunghezza << endl;

    return 0;
}

Esercizio 10

Si realizzi un programma in linguaggio C++ che, data una matrice NxM di interi, trovi l’elemento per cui la media degli elementi ad esso adiacenti sia massima. Si stampino le coordinate di tale elemento ed il suo valore.

Si considerino come adiacenti a ciascun elemento i quattro elementi nelle quattro direzioni cardinali. Si tratti inoltre l’ultima colonna come adiacente alla prima, e l’ultima riga come adiacente alla prima. Si supponga che N ed M possano variare tra 1 e 100. I valori di N ed M, così come i valori degli elementi della matrice, vengono acquisiti da tastiera.

Soluzione

Teoria:

Per risolvere questo problema, possiamo iterare attraverso ogni elemento della matrice e calcolare la media degli elementi adiacenti a esso. Le quattro direzioni cardinali sono nord, sud, est e ovest. Tuttavia, dobbiamo gestire il caso in cui l’elemento si trova sul bordo della matrice, dove non ci sono quattro elementi adiacenti in tutte le direzioni.

Per risolvere questo problema, possiamo:

  1. Iterare attraverso ogni elemento della matrice.
  2. Calcolare la media degli elementi adiacenti all’elemento corrente.
  3. Tenere traccia dell’elemento con la media massima.
  4. Stampare le coordinate di tale elemento insieme al suo valore.

Per calcolare la media degli elementi adiacenti, dobbiamo controllare se gli elementi adiacenti esistono nella matrice e, se sì, sommarli e dividere per il numero di elementi considerati.

Codice in C++:

#include <iostream>
#include <vector>

using namespace std;

// Funzione per calcolare la media degli elementi adiacenti a una posizione nella matrice
double mediaAdiacenti(const vector<vector<int>>& matrice, int riga, int colonna, int N, int M) {
    double somma = 0.0;
    int numAdiacenti = 0;

    // Verifica e somma l'elemento a nord
    if (riga > 0) {
        somma += matrice[riga - 1][colonna];
        numAdiacenti++;
    }
    // Verifica e somma l'elemento a sud
    if (riga < N - 1) {
        somma += matrice[riga + 1][colonna];
        numAdiacenti++;
    }
    // Verifica e somma l'elemento a ovest
    if (colonna > 0) {
        somma += matrice[riga][colonna - 1];
        numAdiacenti++;
    }
    // Verifica e somma l'elemento a est
    if (colonna < M - 1) {
        somma += matrice[riga][colonna + 1];
        numAdiacenti++;
    }

    // Calcola e restituisce la media degli elementi adiacenti
    return somma / numAdiacenti;
}

int main() {
    int N, M;
    cout << "Inserisci il numero di righe della matrice (N): ";
    cin >> N;
    cout << "Inserisci il numero di colonne della matrice (M): ";
    cin >> M;

    vector<vector<int>> matrice(N, vector<int>(M));

    // Input degli elementi della matrice
    cout << "Inserisci gli elementi della matrice:" << endl;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            cin >> matrice[i][j];
        }
    }

    double maxMedia = 0.0;
    int maxRiga, maxColonna;

    // Calcola la media degli elementi adiacenti per ogni elemento nella matrice
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            double media = mediaAdiacenti(matrice, i, j, N, M);
            // Se la media è maggiore della massima trovata finora, aggiorna i valori massimi
            if (media > maxMedia) {
                maxMedia = media;
                maxRiga = i;
                maxColonna = j;
            }
        }
    }

    // Stampare le coordinate e il valore dell'elemento con la media degli adiacenti massima
    cout << "L'elemento con la media degli adiacenti massima si trova alla riga " << maxRiga << ", colonna " << maxColonna << " e ha valore " << matrice[maxRiga][maxColonna] << "." << endl;

    return 0;
}
    Back to Blog

    Related Posts

    View All Posts »
    Struct in C++

    Struct in C++

    Le struct rappresentano un elemento fondamentale del linguaggio C++, offrendo un modo flessibile e strutturato per gestire dati complessi. La loro semplicità d'uso e i numerosi vantaggi le rendono uno strumento prezioso per qualsiasi programmatore C++.

    Funzioni in C++

    Funzioni in C++

    Le funzioni in C++ rappresentano un costrutto fondamentale per la programmazione. Vediamo come si definiscono e come si utilizzano