#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&0x01ff) #define TO(i) ((i>>9)&0x01ff) #define WEIGHT(i) (i>>18) #define CONSTRUCT(f, t, w) (((w&0xff) << 18) | (t << 9) | 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\n", FROM(edges[i]), TO(edges[i]), WEIGHT(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 } } printf ("The highest possble quality is 1/%d.\n", sum); } return EXIT_SUCCESS; }