Informatica 2 Liceo Scientifico Scienze Applicate/NobileChimico

Wikibooks, manuali e libri di testo liberi.
Indice del libro

Il NobileChimico[modifica]

Il problema Il nobile chimico Alfredo produce nel suo laboratorio due sostanze liquide potenzialmente inquinanti: l’Aminozalina e il Brinofulo. A fine giornata le deve smaltire in appositi contenitori, dislocati lungo il tragitto che parte dal laboratorio e arriva alla sua abitazione. Per limitare le possibilità d’inquinamento, Alfredo deve distribuire l’Aminozalina nel maggior numero possibile di contenitori mentre deve dividere il Brinofulo nel minor numero possibile di contenitori. Tuttavia Aminozalina e Brinofulo non possono essere assolutamente mescolati nel medesimo contenitore, altrimenti la loro miscela esplode. Ogni volta che raggiunge un contenitore per lo smaltimento dei liquidi, Alfredo deve eseguire una sola delle tre seguenti azioni:

  • (i) versare Aminozalina fino al riempimento del contenitore;
  • (ii) versare Brinofulo fino al riempimento del contenitore;
  • (iii) non versare nulla nel contenitore.

Data la quantità A di litri di Aminozalina e la quantità B di litri di Brinofulo da smaltire, e conoscendo l’elenco degli N contenitori (con rispettiva capacità) nell’ordine secondo cui sono incontrati lungo il tragitto dal laboratorio alla sua abitazione, Alfredo deve decidere se e quale sostanza versare in ciascun contenitore.

Dati di input

Il file input.txt contiene nella prima riga gli interi A e B (rispettivamente i litri di Aminozalina e di Brinofulo da smaltire) e il numero N di contenitori disponibili. Tali valori sono separati da uno spazio. Nelle successive N righe (usando una riga per ogni contenitore) è contenuto un numero per riga: tali numeri rappresentano le capacità dei singoli contenitori elencati nell’ordine in cui vengono incontrati da Alfredo.

Dati di output

Il file output.txt deve contenere N righe, una per ogni contenitore. Ogni riga contiene due numeri separati da uno spazio, rispettivamente il numero di litri di Aminozalina e di Brinofulo smaltiti nel corrispondente contenitore. Si noti che ogni riga deve contenere uno zero nei casi (i) e (ii) descritti sopra, e due zeri nel caso (iii).

Assunzioni

  • • 1 < A, B < 10000
  • • 1 < N < 100
  • • Le singole capacità dei contenitori sono degli interi positivi di valore inferiore a 10000.
  • • Le capacità dei contenitori sono sicuramente sufficienti per smaltire tutta l’Aminozalina e il Brinofulo prodotti.
  • • I dati in input garantiscono l’esistenza di una (e una sola) soluzione ottima, quindi Alfredo ha un unico modo ottimo per smaltire le sostanze.
  • • La soluzione ottima prevede che tutti i contenitori utilizzati vengano riempiti completamente (non puo’ succedere che l’Aminozalina o il Brinofulo terminino prima che i contenitori effettivamente usati per lo smaltimento siano tutti completamente riempiti).

Esempi di input/output

File input.txt File output.txt
20 25 7 1 0
1 0 13
13 4 0
4 5 0
5 8 0
8 2 0
2 0 12
12


#include <iostream>
#include <fstream>
using namespace std;

struct bidone
{ int pos;
  int cap;//capacità
  int a;
  int b;
};

int main(int argc, char *argv[])
{   int qa,qb,n;
    ifstream fi;
    fi.open("input.txt");
    fi>>qa;
    fi>>qb;
    fi>>n;
    int i,j;
    bidone elenco[n];
    for(i=0;i<n;i++)
     { fi>>elenco[i].cap;
       elenco[i].pos=i;
       elenco[i].a=0;
       elenco[i].b=0;
     }
    fi.close();
    
    bidone temp;
    for(i=1;i<n;i++)
     for(j=n-1;j>=i;j--)
      if(elenco[j].cap<elenco[j-1].cap)
       { temp=elenco[j];
       elenco[j]=elenco[j-1];
       elenco[j-1]=temp;
       }
    
    
    i=0;
    while( qa>0)
    { elenco[i].a=elenco[i].cap;
      qa=qa-elenco[i].cap;
      i++;
    }
    
    i=n-1;
    while( qb>0)
    { elenco[i].b=elenco[i].cap;
      qb=qb-elenco[i].cap;
      i--;
    }
    
    for(i=1;i<n;i++)
     for(j=n-1;j>=i;j--)
      if(elenco[j].pos<elenco[j-1].pos)
       { temp=elenco[j];
       elenco[j]=elenco[j-1];
       elenco[j-1]=temp;
       }
    
    ofstream fo;
    fo.open("output.txt");
    for(i=0;i<n;i++)
     fo<<elenco[i].a<<" "<<elenco[i].b<<endl;
    fo.close();
     
       
    system("PAUSE");
    return EXIT_SUCCESS;
}

Descrizione della soluzione : bisogna smaltire la sostanza nei bidoni di capacità più piccola (partendo da quello più piccolo in assoluto e poi a crescere) e la sostanza B in quelli più grandi (partendo da quello più grande e poi a decrescere). I valori di A e B sono assegnati in modo tale che nella sequenza corretta i bidoni utilizzati per lo smaltimento vengano riempiti fper tutta la loro capacità (non ci sono bidoni riempiti solo in parte o situazioni in cui lo smaltimento non è possibile). creo una struct bidone dove cap è la capacità del bidone qa la sostanza A smaltita nel bidone (inizialmente a zero), qb la sostanza B smaltita nel bidone (inizialmente a zero) pos la posizione che occupa il bidone nel percorso dallo stabilimento chimico a casa. Creo un vettore di questi bidoni che sono n, carico i valori delle capacità e posizioni dal file di input. Ordino i vettori in base alla capacità (dal più piccolo al più grande) verso la sostanza A finché non termina partendo da quello più piccolo e passando poi a quelli successi, smaltisco poi la sostanza B partendo da quello più grande e passando poi a quelli precedenti.Riordino il vettore in base alla posizione e stampo i valori qa e qb di ciascun bidone nel file delle soluzioni.