#include #include #define DEBUG 0 #define MAXT 2048 #define TNAMELEN 16 #define TRL 7 char trucks[MAXT][TNAMELEN]; int N, edgeno; unsigned int edges[MAXT*MAXT]; #define FROM(i) (i&0x07ff) #define TO(i) ((i>>12)&0x07ff) #define WEIGHT(i) (i>>24) #define CONSTRUCT(f, t, w) (((w&0xff) << 24) | (t << 12) | f) struct { unsigned father; int size; } uftrucks[MAXT]; int uffind(int a) { int b = a, c; while (uftrucks[b].father != b) b = uftrucks[b].father; while (uftrucks[a].father != a) { c = uftrucks[a].father; uftrucks[a].father = b; a = c; } return b; } int ufunion (int a, int b) { a = uffind(a); b = uffind(b); if (uftrucks[a].size > uftrucks[b].size) { uftrucks[b].father = a; uftrucks[a].size += uftrucks[b].size; } else { uftrucks[a].father = b; uftrucks[b].size += uftrucks[a].size; } return uftrucks[a].father; } void ufinit(int s) { int i; for (i = 0; i < s; i++) { uftrucks[i].size = 1; uftrucks[i].father = i; } } int cmp(const void *a, const void *b) { unsigned int ax = *(unsigned int const *) a; unsigned int bx = *(unsigned int const *) b; return (int)WEIGHT(ax) - (int)WEIGHT(bx); } int main(void) { int i, j, k; int diffs, ksize, sum; for (;;) { scanf("%d ", &N); if (!N) break; edgeno = 0; for (i = 0; i < N; i++) fgets(trucks[i], TNAMELEN, stdin); for (i = 0; i < N; i++) for (j = i+1; j < N; j++) { diffs = 0; for (k = 0; k < TRL; k++) if (trucks[i][k] != trucks[j][k]) diffs++; edges[edgeno++] = CONSTRUCT(i, j, diffs); } qsort(edges, edgeno, sizeof(*edges), cmp); ksize = 0; sum = 0; ufinit(N); for (i = 0; ksize < N-1; i++) { #if DEBUG printf("From: %d, To: %d, Weight: %d, I: %d, Ksize: %d, UFF: %d, UFT %d ", FROM(edges[i]), TO(edges[i]), WEIGHT(edges[i]), i, ksize, uffind(FROM(edges[i])), uffind(TO(edges[i]))); #endif if (uffind(FROM(edges[i])) != uffind(TO(edges[i]))) { ufunion(FROM(edges[i]), TO(edges[i])); ksize++; sum += WEIGHT(edges[i]); #if DEBUG printf("Added\n"); #endif } else { #if DEBUG printf("\n"); #endif } } printf ("The highest possible quality is 1/%d.\n", sum); } return EXIT_SUCCESS; }