201 lines
4.3 KiB
C
201 lines
4.3 KiB
C
// Laboratorio 6 - Esercizio 2
|
|
// Matteo Schiff - s295565
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
int fZ(int z, int r, int t, int s, int len);
|
|
int fR(int z, int r, int t, int s, int len);
|
|
int fS(int z, int r, int t, int s, int len);
|
|
int fT(int z, int r, int t, int s, int len);
|
|
|
|
enum Pietra{zaffiro, rubino, topazio, smeraldo};
|
|
|
|
int *cache;
|
|
int mz, mr, mt, ms;
|
|
|
|
// Funzioni helper per semplificare la memorizzazione
|
|
// NOTA se `getCache` restituisce 0 vuol dire che la collana non è ancora stata analizzata
|
|
int getCache(int p, int z, int r, int t, int s) {
|
|
return *(cache + p*mz*mr*mt*ms + z*mr*mt*ms + r*mt*ms + t*ms + s);
|
|
}
|
|
|
|
void saveCache(int p, int z, int r, int t, int s, int val) {
|
|
*(cache + p*mz*mr*mt*ms + z*mr*mt*ms + r*mt*ms + t*ms + s) = val;
|
|
}
|
|
|
|
int fZ(int z, int r, int t, int s, int len) {
|
|
if (len != 0 && getCache(zaffiro, z,r,t,s) != 0) {
|
|
return getCache(zaffiro,z,r,t,s);
|
|
}
|
|
|
|
int x = -1;
|
|
int m;
|
|
if (z > 0) {
|
|
m = fZ(z-1,r,t,s,len +1);
|
|
if (m > x)
|
|
x = m;
|
|
}
|
|
|
|
if (r > 0) {
|
|
m = fR(z,r-1,t,s,len +1);
|
|
if (m > x)
|
|
x = m;
|
|
}
|
|
|
|
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
|
|
if (x == -1) {
|
|
saveCache(zaffiro,z,r,t,s,len);
|
|
return len;
|
|
}
|
|
|
|
// se no restituisco il massimo fin'ora
|
|
saveCache(zaffiro,z,r,t,s,x);
|
|
return x;
|
|
}
|
|
|
|
int fR(int z, int r, int t, int s, int len) {
|
|
if (len != 0 && getCache(rubino, z,r,t,s) != 0) {
|
|
return getCache(rubino,z,r,t,s);
|
|
}
|
|
|
|
int x = -1;
|
|
int m;
|
|
if (s > 0) {
|
|
m = fS(z,r,t,s-1,len +1);
|
|
if (m > x)
|
|
x = m;
|
|
}
|
|
|
|
if (t > 0) {
|
|
m = fT(z,r,t-1,s,len +1);
|
|
if (m > x)
|
|
x = m;
|
|
}
|
|
|
|
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
|
|
if (x == -1) {
|
|
saveCache(rubino,z,r,t,s,len);
|
|
return len;
|
|
}
|
|
|
|
// se no restituisco il massimo fin'ora
|
|
saveCache(rubino,z,r,t,s,x);
|
|
return x;
|
|
}
|
|
|
|
int fT(int z, int r, int t, int s, int len) {
|
|
if (len != 0 && getCache(topazio, z,r,t,s) != 0) {
|
|
return getCache(topazio,z,r,t,s);
|
|
}
|
|
|
|
int x = -1;
|
|
int m;
|
|
if (z > 0) {
|
|
m = fZ(z-1,r,t,s,len +1);
|
|
if (m > x)
|
|
x = m;
|
|
}
|
|
|
|
if (r > 0) {
|
|
m = fR(z,r-1,t,s,len +1);
|
|
if (m > x)
|
|
x = m;
|
|
}
|
|
|
|
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
|
|
if (x == -1) {
|
|
saveCache(topazio,z,r,t,s,len);
|
|
return len;
|
|
}
|
|
|
|
// se no restituisco il massimo fin'ora
|
|
saveCache(topazio,z,r,t,s,x);
|
|
return x;
|
|
}
|
|
|
|
int fS(int z, int r, int t, int s, int len) {
|
|
if (len != 0 && getCache(smeraldo, z,r,t,s) != 0) {
|
|
return getCache(smeraldo,z,r,t,s);
|
|
}
|
|
|
|
int x = -1;
|
|
int m;
|
|
if (s > 0) {
|
|
m = fS(z,r,t,s-1,len +1);
|
|
if (m > x)
|
|
x = m;
|
|
}
|
|
|
|
if (t > 0) {
|
|
m = fT(z,r,t-1,s,len +1);
|
|
if (m > x)
|
|
x = m;
|
|
}
|
|
|
|
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
|
|
if (x == -1) {
|
|
saveCache(smeraldo,z,r,t,s,len);
|
|
return len;
|
|
}
|
|
|
|
// se no restituisco il massimo fin'ora
|
|
saveCache(smeraldo,z,r,t,s,x);
|
|
return x;
|
|
}
|
|
|
|
void solveCase(int z, int r, int t, int s) {
|
|
mz = z+1;
|
|
mr = r+1;
|
|
mt = t+1;
|
|
ms = s+1;
|
|
cache = calloc(4*mz*mr*mt*ms, sizeof(int));
|
|
|
|
int max = z+r+t+s;
|
|
|
|
int res = -1, x;
|
|
|
|
printf("zaffiri = %d, rubini = %d, topazi = %d, smeraldi = %d; numero pietre = %d\n", z,r,t,s,max);
|
|
|
|
x = fZ(z-1,r,t,s,1);
|
|
if (x > res)
|
|
res = x;
|
|
|
|
x = fR(z,r-1,t,s,1);
|
|
if (x > res)
|
|
res = x;
|
|
|
|
x = fS(z,r,t,s-1,1);
|
|
if (x > res)
|
|
res = x;
|
|
|
|
x = fT(z,r,t-1,s,1);
|
|
if (x > res)
|
|
res = x;
|
|
free(cache);
|
|
|
|
printf("Collana massima di lunghezza %d\n", res);
|
|
fflush(stdout);
|
|
}
|
|
|
|
int main() {
|
|
int z, r, t, s, N = 0;
|
|
|
|
FILE *fp;
|
|
|
|
if ((fp = fopen("hard_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", &z, &r, &t, &s);
|
|
printf("Test case %d\n", i+1);
|
|
solveCase(z,r,t,s);
|
|
}
|
|
|
|
fclose(fp);
|
|
} |