#include #include #define MAXK 100 /* * Správa pomocných souborů, aby bylo zjevné, že jich řešení * nepoužívá více než 2k+2. Praktičtější by bylo použít tmpfile(). */ static unsigned num_tmp_files; static FILE *file_pool[2 * MAXK]; static unsigned file_pool_size; static FILE * get_temporary_file(void) { FILE *ret; if (file_pool_size > 0) { ret = file_pool[--file_pool_size]; rewind(ret); } else { char tmpname[10]; sprintf(tmpname, "tmp%d", num_tmp_files++); ret = fopen(tmpname, "w+"); } return ret; } static void release_tmp_file(FILE *f) { file_pool[file_pool_size++] = f; } static void remove_temporary_files(void) { for (unsigned i = 0; i < num_tmp_files; i++) { char tmpname[10]; sprintf(tmpname, "tmp%d", i); remove(tmpname); } } /* * Seznam intervalů ke zpracování. Interval obsahuje c čísel * paketů a tato čísla jsou uložena v souboru s. */ typedef struct { unsigned f, t, c; FILE *s; } interval; static interval ke_zpracovani[MAXK]; static unsigned int_ke_zprac; /* * Zpracuj interval , v němž je c čísel, uložených v souboru s. * Interval budeme dělit na d podintervalů. */ static void zpracuj_interval(unsigned f, unsigned t, unsigned c, FILE *s, unsigned d) { FILE *tmpfs[MAXK]; unsigned pocet[MAXK]; unsigned m = t - f + 1; unsigned i, plen, a, ai; for (i = 0; i < d; i++) pocet[i] = 0; /* * Jestliže je délka intervalu větší než d, přípravme pomocné * soubory. Jinak na této úrovni rekurze končíme s intervaly délky 1. */ if (m > d) { for (i = 0; i < d; i++) tmpfs[i] = get_temporary_file(); plen = (m + d - 1) / d; } else plen = 1; /* Rozdělme čísla paketů do podintervalů. */ for (i = 0; i < c; i++) { fscanf(s, "%u", &a); ai = (a - f) / plen; pocet[ai]++; if (m > d) fprintf(tmpfs[ai], "%d\n", a); } /* * Intervaly, které obsahují alespoň jedno chybějící číslo, * zařadíme do sezamu ke zpracování (nebo toto chybějící číslo * vypíšeme, pokud je celý interval prázdný). */ for (i = 0; i < d; i++) { unsigned l = f + plen * i, u = l + plen - 1; interval nint; if (u > t) u = t; if (pocet[i] == u - l + 1) { if (m > d) release_tmp_file(tmpfs[i]); continue; } if (pocet[i] == 0) { unsigned j; for (j = l; j <= u; j++) printf("%d ", j); if (m > d) release_tmp_file(tmpfs[i]); continue; } nint.f = l; nint.t = u; nint.c = pocet[i]; rewind(tmpfs[i]); nint.s = tmpfs[i]; ke_zpracovani[int_ke_zprac++] = nint; } } int main(void) { FILE *fin = fopen("pakety.txt", "r"); unsigned n, k, d; fscanf(fin, "%u%u", &n, &k); d = k < 2 ? 2 : k; int_ke_zprac = 0; zpracuj_interval(1, n, n - k, fin, d); while (int_ke_zprac > 0) { interval a = ke_zpracovani[--int_ke_zprac]; zpracuj_interval(a.f, a.t, a.c, a.s, d); release_tmp_file(a.s); } remove_temporary_files(); return 0; }