#include #include struct edge { short from, to, q; } edges[2000 * 1000 + 10]; int nedges; char data[10000][10]; int sums[10000]; char line[100]; int n; int rank[10000]; int parent [10000]; void init () { int i; for (i = 0; i < n; i++) { rank[i] = 0; parent[i] = i; } } int find(int v) { int x = v; while (x != parent[x]) { x = parent[x]; } while (v != parent[v]) { int vv = parent[v]; parent[v] = x; v = vv; } return x; } void un (int a, int b) { a = find(a); b = find(b); if (rank[a] < rank[b]) { parent[a] = b; } else if (rank[a] > rank[b]) { parent[b] = a; } else { parent[a] =b; rank[b] ++; } } int cmp (struct edge *a, struct edge*b) { return a->q - b->q; } int main() { int i,j,k,s; int m; while(1) { gets(line); sscanf(line,"%d",&n); if (!n) break; i = n; nedges = 0; while (i--) { gets(data[i]); sums[i] = 0; } for(i = 0; i < n; i++) { for (j = i+1; j < n; j++) { s = 0; for (k = 0; k < 7; k++) { if (data[i][k] != data[j][k]) s++; } edges[nedges].from = i; edges[nedges].to = j; edges[nedges++].q = s; edges[nedges].from = j; edges[nedges].to = i; edges[nedges++].q = s; } } qsort(edges,nedges,sizeof(struct edge),cmp); m = 0; init(); for (i = 0; i < nedges; i++ ) { int a = find(edges[i].from); int b = find(edges[i].to); if (a != b) { un (a, b); m += edges[i].q; } } printf("The highest possible quality is 1/%d.\n",m); } return 0; }