Problema "Somma pari massima v2.0"

Ho provato con questo codice e il programma funziona con gli esempi riportati e con alcuni miei esempi… Ho ricevuto inizialmente 0/100… Quando ho modificato i parametri delle assunzioni (ho incluso N=1 e N= 100000) ho ricevuto 70/100 ma stranamente niente 100/100…

Il codice è questo:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    int vettore[100000]={0},somma_pari=0,n=0,i=0,j,var=0;
    fstream file;
    file.open(“input.txt”,ios::in);
    if(!file.is_open())
    {
        file.open(“output.txt”,ios::out);
        file<<-1;
        file.close();
        return -1;
    }
    file>>n;
    if(n<1 || n>100000)
    {
        file.open(“output.txt”,ios::out);
        file<<-1;
        file.close();
        return -1;
    }
    do
    {
        file>>vettore[i];
        if(vettore[i]<0 || vettore[i]>1000000)
        {
            file.open(“output.txt”,ios::out);
            file<<-1;
            file.close();
            return -1;
        }
        i++;
    }while(!file.eof());
    file.close();
    for(i=0; i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            if((vettore[i]+vettore[j])%2==0 && vettore[i]+vettore[j]>somma_pari && i!=j)
                {
                    somma_pari= vettore[i]+vettore[j];
                    var++;
                }
        }
    }
    file.open(“output.txt”,ios::out);
    if(var==0)
        file<<-1;
    else
        file<<somma_pari;
    file.close();
}

Se clicchi sull’ID numerico della tua sottoposizione ti viene elencato l’esito per ogni caso di test. A occhio e croce direi che leggerai qualcosa del tipo “Execution timed out” ovvero che hai superato il tempo di esecuzione messo a disposizione per il tuo programma.

Aaaah, si hai ragione! non me ero accorto di questa finestra… Grazie mille!

Comunque tutti quei controlli in lettura o apertura del file non ti servono per i problemi (viene sempre assicurato il rispetto dei limiti del problema).

In ogni caso non ti serve nemmeno un vettore, basta che pensi con quali categorie di numeri puoi ottenere una somma pari e lo risolvi in lettura :slight_smile:
Comunque tutti quei controlli in lettura o apertura del file non ti servono per i problemi (viene sempre assicurato il rispetto dei limiti del problema).

VashTheStampede

Sono d’accordo con te, in parte. Intanto, in generale, può essere una buona
cosa che il proprio programma segnali in qualche modo che le assunzioni
non vengono rispettate (ad esempio: quando vuoi eseguire un input creato
a mano oppure un input gigante, generato automaticamente con un altro
programma).

Ho visto gente a volte che metteva un grosso if (le assuzioni del problema sono rispettate) { tutto il programma }
e questo oltre ad essere inutile (perché se non vengono
rispettate il tuo programma non fa nulla, come ti accorgerai che il tuo
programma non ha fatto nulla per colpa delle assunzioni?) rende il programma poco leggibile dato che aumenta il livello d’indentazione del programma…

If you need more than 3 levels of indentation, you’re screwed anyway, and should fix your program.

Linus Torvalds

Non prendiamo alla lettera le parole di Linus, che spesso esagera… comunque @Rob97
quantomeno ha fatto una cosa un po’ più furba :slight_smile: ovvero, se non
vengono rispettate le assunzioni fa uscire il programma con exit code
uguale a -1 (quindi ha modo di accorgersi se le assunzioni non sono
rispettate), altrimenti esegue il programma (quindi non sono aumentate
le indentazioni).

Tuttavia, l’idea di @Rob97 di usare l’exit code come indicatore è un “reinventare la ruota” dato che nella libreria assert.h è presente una funzione che fa esattamente quello, ovvero terminare il programma con exit code diverso da zero (ma meglio!).

if (n<1 || n>100000) {
return -1;
}

Con un semplice #include <assert.h> si può utilizzare la funzione assert(int) in questo modo:

assert(n>=1 && n<=100000);

La cosa migliore non è tanto il fatto che serva meno codice per scriverla, quanto che (se l’input non rispetta le assunzioni) assert scriverà a video un messaggio del tipo:

prova: prova.cpp:6: int main(): Assertion `n>=1 && n<=100000’ failed.
[1]    3136 abort (core dumped)  ./prova

Ti dice esattamente l’asserzione fallita (n>=1 && n<=100000) e ti dice anche in quale riga si trova (6). Più chiaro di così!


P.S. Oltre a “passare ad assert”, @Rob97 farebbe bene ad utilizzare delle costanti, del tipo:

#define MAXN 100000

In modo da dichiarare gli array con int array[MAXN] e da controllare le assunzioni con assert(n>=1 && n<=MAXN).

Una volta ho visto qualcuno dichiarare l’array della dimensione giusta (100000) ma controllare le assunzioni del problema usando la dimensione sbagliata (10000), questi bug te li vai a cercare se non usi le costanti :slight_smile:


P.P.S. Un’altra cosa comoda degli assert è che è sufficiente aggiungere in cima al proprio file.c/cpp (o comunque prima di #include<assert.h>) la riga:

#define NDEBUG

che ha l’effetto di ignorare automaticamente tutte le chiamate ad assert(), il che può essere comodo, ad esempio, quando si usano cose tipo assert(controlla()) dove controlla() può essere una funzione molto lenta…