Aiuto Excursion

Ciao a tutti,

Non riesco ad andare oltre 70/100 con 3 testcase (10,11,13) falliti nel subtask 3 (H, W ≤ 10);
il resto, stranamente, è tutto corretto :face_with_raised_eyebrow:
Qualcuno mi può aiutare a capire dove sbaglio? Magari fornendo anche un esempio se non chiedo troppo :relaxed:
Grazie in anticipo!

Codice: https://pastebin.com/WMYdhb02

Un esempio piccolo (ma diverso da quelli “ufficiali”) su cui la tua soluzione sbaglia dovrebbe essere il seguente:

2 5
8 1 4 0 5
6 9 3 2 7
1 Mi Piace

Ho sostituito il minore nell’else if che non aveva alcun senso con un più ragionevole “==” ahaha; ovviamente ho modificato tutti gli else if. Nonostante ciò il testcase 10 rimane errato. Adesso l’esempio che mi hai fatto te mi restituisce 10, che mi sembra giusto, con questo percorso: 8→6→9→3→2→0→4→3→9→6→8

if (abs(a[i][j] - a[i][j-1]) < mini){
            mini = abs(a[i][j] - a[i][j-1]);
            imin = i;
            jmin = j-1;
        } else if (abs(a[i][j] - a[i][j-1]) < mini){
            if (a[i][j-1] < a[imin][jmin]){
                imin = i;
                jmin = j-1;
            }

C’è qualcos’altro che mi sfugge?

10 è corretto per il caso di esempio presentato sopra.
Riesci a rimandare il codice completo dopo le modifiche?

1 Mi Piace

Ecco qua https://pastebin.com/xLpbt5Nh

Prova a verificare con quest’altro esempio:

2 4
1 5 7 6
0 3 4 2

In problemi di questo genere è necessario prestare estrema attenzione ai vari casi perché è facile perdersene qualcuno :wink:

1 Mi Piace

Il mio codice restituisce 10, e facendolo a mano mi sembra che il risultato sia corretto… :no_mouth:
L’ordine (sia quello del programma che quello fatto a mano) è 1→0→3→4→2→6→7→5→3→0→1

Interessante, io ottengo 3 eseguendo il tuo programma :stuck_out_tongue:

Questa istruzione alla riga 70

if (abs(a[i][j] - a[i][j+1]) < mini){

usa la variabile mini che non sempre però viene inizializzata e potenzialmente può contenere qualsiasi valore (a seconda di cosa ha in memoria il computer a quell’indirizzo).

C’è anche una pagina su Wikipedia che descrive ciò: Uninitialized variable.

In casi come questo è provvidenziale l’utilizzo di un tool di controllo della memoria (valgrind se usi linux). Sulla tua soluzione riporta infatti:

==7387== Conditional jump or move depends on uninitialised value(s)
==7387==    at 0x10906F: visita(int, int) (in /home/luca/git/oli_squadre/problemi/excursion/sol/a.out)
==7387==    by 0x1091C8: visita(int, int) (in /home/luca/git/oli_squadre/problemi/excursion/sol/a.out)
==7387==    by 0x109372: main (in /home/luca/git/oli_squadre/problemi/excursion/sol/a.out)
1 Mi Piace

Io con l’ultimo codice che ho postato (https://pastebin.com/xLpbt5Nh) ottengo 10 come risultato.

Non so che dirti ahaha, l’ho copiato e incollato da pastebin 3 volte per sicurezza e mi ha restituito sempre 10 :laughing: Può darsi che ciò sia dovuto al fatto che (forse) utilizziamo due compilatori differenti?
Io uso CodeBlocks 16.01 con il GNU GCC compiler.

Poi la variabile mini in teoria dovrebbe venire sempre inizializzata, ho omesso
if (!esiste){ esiste = 1; imin = i; jmin = j-1; mini = abs(a[i][j] - a[i][j-1]); }
di proposito dall’ultimo controllo della casella proprio per questo motivo.

Oops, avevi ragione te :sweat_smile:
Ho aggiunto if (!esiste){ imin = i; jmin = j+1; mini = abs(a[i][j] - a[i][j+1]); }
e ho preso 100/100.

Preso dalla foga mi ero dimenticato di considerare il fatto che, se il percorso arriva in un angolo, la casella successiva può essere una sola.
Omettere if (!esiste){ imin = i; jmin = j+1; mini = abs(a[i][j] - a[i][j+1]); }
è dunque incorretto, in quanto altrimenti, come hai già detto, viene effettuata un’operazione su una variabile non inizializzata.

Grazie mille per l’aiuto e per la pazienza Luca!