#include #include #include #include #ifdef __PROGTEST__ #define debug(...) ((void)0) #else #define debug(fmt, ...) \ printf("[DEBUG %s:%d %s()] " fmt "\n", __FILE__, __LINE__, \ __func__, ##__VA_ARGS__) #endif typedef long long int lli; typedef long double ld; typedef struct rails_t { lli r1; lli r2; lli d; } rails_t; typedef struct eea_gcd_t { lli g; lli x; lli y; } eea_gcd_t; int invalid_input() { printf("Nespravny vstup.\n"); return EXIT_FAILURE; } eea_gcd_t extended_euclidian_gcd(lli a, lli b) { if (a == 0) { eea_gcd_t res; res.g = b; res.x = 0; res.y = 1; return res; } eea_gcd_t res = extended_euclidian_gcd(b % a, a); lli x = res.y - (b / a) * res.x; lli y = res.x; res.x = x; res.y = y; return res; } lli find_solutions(rails_t rails, bool verbose) { lli variants = 0; if (rails.d == 0) { debug("Zero total distance"); if (verbose) { printf("= %lld * 0 + %lld * 0\n", rails.r1, rails.r2); } return 1; } if (rails.r1 == 0 && rails.d % rails.r2 == 0) { if (verbose) { printf("= %lld * %lld + %lld * 0\n", rails.r1, rails.d / rails.r2, rails.r2); } return 1; } if (rails.r2 == 0 && rails.d % rails.r1 == 0) { if (verbose) { printf("= %lld * 0 + %lld * %lld\n", rails.r1, rails.r2, rails.d / rails.r1); } return 1; } eea_gcd_t eea = extended_euclidian_gcd(rails.r1, rails.r2); lli g = eea.g; if (rails.d % g != 0) { return 0; } ld d_g = (ld)rails.d / (ld)g; ld x0 = (ld)eea.x * d_g; ld y0 = (ld)eea.y * d_g; lli a_g = rails.r1 / g; lli b_g = rails.r2 / g; lli n_min = (lli)ceil(-x0 / (ld)b_g); lli n_max = (lli)floor(y0 / (ld)a_g); if (n_max < n_min) { return 0; } variants += n_max - n_min + 1; if (verbose) { for (lli n = n_min; n <= n_max; n++) { lli x = x0 + n * b_g; lli y = y0 - n * a_g; printf("= %lld * %lld + %lld * %lld\n", rails.r1, x, rails.r2, y); } } return variants; } int main() { printf("Delky koleji:\n"); lli rail_length_1 = -1, rail_length_2 = -1; if (scanf(" %lld %lld", &rail_length_1, &rail_length_2) != 2 || (rail_length_1 <= 0 || rail_length_2 <= 0) || (rail_length_1 == rail_length_2)) { return invalid_input(); } printf("Vzdalenost:\n"); lli total_distance = 0; char operand; if (scanf(" %c %lld", &operand, &total_distance) != 2 || (operand != '+' && operand != '-')) { return invalid_input(); } if (total_distance < 0) { return invalid_input(); } lli variants = 0; bool verbose = operand == '+'; if (rail_length_1 > 0 && rail_length_2 > 0) { rails_t rails; rails.r1 = rail_length_1; rails.r2 = rail_length_2; rails.d = total_distance; variants += find_solutions(rails, verbose); } if (variants != 0) { printf("Celkem variant: %lld\n", variants); } else { printf("Reseni neexistuje.\n"); } }