// Laboratorio 4 - Esercizio 4 - item.c // Matteo Schiff - s295565 #include #include #include enum Pietra{zaffiro, rubino, topazio, smeraldo}; // Ho messo queste variabili globali per diminuire il numero di parametri // di `esploraSoluzioni` per migliorarne la leggibilità // Questi numeri sono costanti per ogni set int vz, vr, vt, vs, max_rip; void esploraSoluzioni(int z, int r, int t, int s, int nz, int ns, int cur_rip, int len, int val, int * tmp, int * max, int*maxlen, int * sol) { int added = false; if (z > 0 && (nz +1) <= ns) { tmp[len] = zaffiro; if (len == 0 || tmp[len - 1] == topazio) { esploraSoluzioni(z-1,r,t,s,nz+1,ns,1,len +1,val+vz,tmp,max,maxlen,sol); added = true; } if (len != 0 && tmp[len - 1] == zaffiro && cur_rip < max_rip) { esploraSoluzioni(z-1,r,t,s,nz+1,ns,cur_rip+1,len +1,val+vz,tmp,max,maxlen,sol); added = true; } } if (s > 0) { tmp[len] = smeraldo; if (len == 0 || tmp[len - 1] == rubino) { esploraSoluzioni(z,r,t,s-1,nz,ns+1,1,len +1,val+vs,tmp,max,maxlen,sol); added = true; } if (len != 0 && tmp[len - 1] == smeraldo && cur_rip < max_rip) { esploraSoluzioni(z,r,t,s-1,nz,ns+1,cur_rip+1,len +1,val+vs,tmp,max,maxlen,sol); added = true; } } if (r > 0 && (len == 0 || (tmp[len - 1] == zaffiro || tmp[len - 1] == topazio))) { tmp[len] = rubino; esploraSoluzioni(z,r-1,t,s,nz,ns,1,len +1,val+vr,tmp,max,maxlen,sol); added = true; } if (t > 0 && (len == 0 || (tmp[len - 1] == smeraldo || tmp[len - 1] == rubino))) { tmp[len] = topazio; esploraSoluzioni(z,r,t-1,s,nz,ns,1,len +1,val+vt,tmp,max,maxlen,sol); added = true; } // se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo if (!added) { if (val >= *max) { *max = val; *maxlen = len; for (int i = 0; i < len; i++) { sol[i] = tmp[i]; } } } } void solveCase(int z, int r, int t, int s) { int maxL = z+r+t+s; int max = 0; int maxlen = 0; int * tmp = malloc(maxL * sizeof(int)); int * sol = malloc(maxL * sizeof(int)); printf("zaffiri = %d (valore: %d), rubini = %d (valore: %d), topazi = %d (valore: %d), smeraldi = %d (valore: %d); numero pietre = %d {max_rip = %d}\n", z, vz,r,vr,t,vt,s,vs,maxL, max_rip); esploraSoluzioni(z,r,t,s,0,0,0,0,0,tmp,&max,&maxlen,sol); printf("Collana con valore massimo %d, lunghezza %d\n", max, maxlen); for(int i = 0; i < maxlen; i++) { switch (sol[i]) { case zaffiro: printf("z "); break; case rubino: printf("r "); break; case smeraldo: printf("s "); break; case topazio: printf("t "); break; default: break; } } putc('\n', stdout); fflush(stdout); free(tmp); free(sol); } int main() { int z, r, t, s, N = 0; FILE *fp; if ((fp = fopen("test_set.txt", "r")) == NULL) { puts("Impossibile aprire il file"); return 1; } fscanf(fp, "%d", &N); for (int i = 0; i < N; i++) { fscanf(fp, " %d %d %d %d %d %d %d %d %d", &z, &r, &t, &s, &vz, &vr, &vt, &vs, &max_rip); printf("Test case %d\n", i+1); solveCase(z,r,t,s); } fclose(fp); }