int main() { int i, j, k, n; char *p, *q; read(); wordlen = (int *)malloc(nr_words * sizeof(int)); for (i = 0; i < nr_words; i++) wordlen[i] = strlen(words[i]); wordmrk = (unsigned char *)malloc(i = ((nr_words + 7) / 8)); memset(wordmrk, '\0', i); for (i = 0; i < nr_words; i++) { n = wordlen[i]; for (j = i + 1; j < nr_words && wordlen[j] > n; j++) { p = words[i]; q = words[j]; for (k = 0; k < n && *p++ == *q++; k++); if (k == n && is_word(q)) MARKWORD(j); else if (k < n) break; } } for (i = 0; i < nr_words; i++) if (ISMARKED(i)) printf("%s\n", words[i]); fflush(stdout); return 0; }
/* ******************************************************************** This routines sorts a[0] ... a[n-1] using the fact that in their common prefix, after offset characters, there is a suffix whose rank is known. In this routine we call this suffix anchor (and we denote its position and rank with anchor_pos and anchor_rank respectively) but it is not necessarily an anchor (=does not necessarily starts at position multiple of Anchor_dist) since this function is called by pseudo_anchor_sort(). The routine works by scanning the suffixes before and after the anchor in order to find (and mark) those which are suffixes of a[0] ... a[n-1]. After that, the ordering of a[0] ... a[n-1] is derived with a sigle scan of the marked suffixes. ******************************************************************** */ static void general_anchor_sort(Int32 *a, Int32 n, Int32 anchor_pos, Int32 anchor_rank, Int32 offset) { int integer_cmp(const void *, const void *); Int32 sb, lo, hi; Int32 curr_lo, curr_hi, to_be_found, i,j; Int32 item; void *ris; assert(Sa[anchor_rank]==anchor_pos); /* ---------- get bucket of anchor ---------- */ sb = Get_small_bucket(anchor_pos); lo = BUCKET_FIRST(sb); hi = BUCKET_LAST(sb); assert(sb==Get_small_bucket(a[0]+offset)); // ------ sort pointers a[0] ... a[n-1] as plain integers qsort(a,n, sizeof(Int32), integer_cmp); // ------------------------------------------------------------------ // now we scan the bucket containing the anchor in search of suffixes // corresponding to the ones we have to sort. When we find one of // such suffixes we mark it. We go on untill n sfx's have been marked // ------------------------------------------------------------------ curr_hi = curr_lo = anchor_rank; // the anchor must correspond to a suffix to be sorted #if DEBUG item = anchor_pos-offset; assert(bsearch(&item,a,n,sizeof(Int32), integer_cmp)); #endif MARK(curr_lo); // scan suffixes preceeding and following the anchor for(to_be_found=n-1;to_be_found>0; ) { // invariant: the next positions to check are curr_lo-1 and curr_hi+1 assert(curr_lo > lo || curr_hi < hi); while (curr_lo > lo) { item = Sa[--curr_lo]-offset; ris = bsearch(&item,a,n,sizeof(Int32), integer_cmp); if(ris) {MARK(curr_lo); to_be_found--;} else break; } while (curr_hi < hi) { item = Sa[++curr_hi]-offset; ris = bsearch(&item,a,n,sizeof(Int32), integer_cmp); if(ris) {MARK(curr_hi); to_be_found--;} else break; } } // sort a[] using the marked suffixes for(j=0, i=curr_lo;i<=curr_hi;i++) if(ISMARKED(i)) { UNMARK(i); a[j++] = Sa[i] - offset; } assert(j==n); // make sure n items have been sorted }
void walk_faces(int i, int face_colour) { int r, c, s; int v1, v2, v3; int a1, a2, a3; vertices_of_face(i, &v1, &v2, &v3); // If we have already visited this face then there // is nothing to do here so leave. if (ISMARKED(facestart[i])) return; // Otherwise we tag this face and recurse on the // three neighbours. MARKLO(facestart[i]); // printf("marking face %d\n", i); // If all three vertices of this face are uncoloured // then we are entering walk_faces for for the first time // so we arbitrarily 3-colour the vertices of this face. if (vertex_colour[v1] < 0 && vertex_colour[v2] < 0 && vertex_colour[v3] < 0) { vertex_colour[v1] = 0; vertex_colour[v2] = 1; vertex_colour[v3] = 2; } else if (vertex_colour[v1] >= 0 && vertex_colour[v2] >= 0 && vertex_colour[v3] >= 0) { // Terminating case, do nothing. } else { // Two vertices must be coloured so we can colour the third. if (vertex_colour[v1] >= 0 && vertex_colour[v2] >= 0) { assert(vertex_colour[v3] < 0); vertex_colour[v3] = other_colour(vertex_colour[v1], vertex_colour[v2]); } else if (vertex_colour[v1] >= 0 && vertex_colour[v3] >= 0) { assert(vertex_colour[v2] < 0); vertex_colour[v2] = other_colour(vertex_colour[v1], vertex_colour[v3]); } else if (vertex_colour[v2] >= 0 && vertex_colour[v3] >= 0) { assert(vertex_colour[v1] < 0); vertex_colour[v1] = other_colour(vertex_colour[v2], vertex_colour[v3]); } else { printf("%d, %d, %d\n", vertex_colour[v1], vertex_colour[v2], vertex_colour[v3]); assert(FALSE); } } ordered_triple(v1, v2, v3, &r, &c, &s); // Have we seen the row label r before? If not, make a note of how // we will really present it. if (row_label[r] < 0) { row_label[r] = max_row_label; max_row_label++; } if (col_label[c] < 0) { col_label[c] = max_col_label; max_col_label++; } if (sym_label[s] < 0) { sym_label[s] = max_sym_label; max_sym_label++; } triple e; e.x = row_label[r]; e.y = col_label[c]; e.z = sym_label[s]; if (face_colour == 0) { T1[max_entry_index1] = e; max_entry_index1++; } else { // face_colour == 1 T2[max_entry_index2] = e; max_entry_index2++; } // tags of the three adjacent faces a1 = facestart[i]->invers->tag; a2 = facestart[i]->invers->prev->invers->tag; a3 = facestart[i]->invers->prev->invers->prev->invers->tag; if (face_colour == 0) face_colour = 1; else face_colour = 0; walk_faces(a1, face_colour); walk_faces(a2, face_colour); walk_faces(a3, face_colour); }