#include #include #define MAX_N 1000000 int N; int M[MAX_N], K[MAX_N]; int i; void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } int invers(int a, int b) { int A = a; // Rozšířený Euklidův algoritmus z kuchačky // A = číslo, modulo kterým počítáme // B = číslo, které invertujeme int Aa = 1, Ba = 0, Ab = 0, Bb = 1; if (b > a) { swap(&a, &b); swap(&Aa, &Ab); swap(&Ba, &Bb); } while (b > 0) { Aa -= (a / b) * Ab; Ba -= (a / b) * Bb; a %= b; swap(&a, &b); swap(&Aa, &Ab); swap(&Ba, &Bb); } if (a > 1) { printf("Řešení neexistuje.\n"); exit(1); } if (Ba < 0) Ba += A; return Ba; } int main() { // Načtení vstupu - počet policistů, velikosti řad a zbytky scanf("%d", &N); for (i = 0; i < N; i++) { scanf("%d%d", &M[i], &K[i]); } // "Prefixové a sufixové násobky" int A[MAX_N], B[MAX_N]; B[N] = 1; A[0] = 1; // S je součin všech M int S = 1; for (i = 0; i < N; i++) { A[i + 1] = A[i] * M[i]; B[N - (i + 1)] = B[N - i] * M[N - (i + 1)]; S *= M[i]; } int reseni = 0; for (i = 0; i < N; i++) { // Spočítej Ri modulo M_i int Si = A[i] * B[i + 1]; int Ri = Si % M[i]; int Ri_invers = invers(M[i], Ri); int Qi = Ri_invers * Si; reseni = (reseni + (Qi * K[i])) % S; } // Teď máme spočítáno, kolik policistů musí být na stanici bez škrtání. printf("Bez škrtání: %d\n", reseni); int nejlepsi_zbytek, nejlepsi_skrtnuti; for (i = 0; i < N; i++) { int Si = A[i] * B[i + 1]; int se_skrtnutim = reseni % Si; if (i == 0 || se_skrtnutim < nejlepsi_zbytek) { nejlepsi_skrtnuti = i; nejlepsi_zbytek = se_skrtnutim; } } printf("Nejlepší škrtnutí: (%d, %d).\n", M[nejlepsi_skrtnuti], K[nejlepsi_skrtnuti]); printf("Na stanici musí zůstat %d policistů.\n", nejlepsi_zbytek); return 0; }