Run Time: 0.000
Ranking (as of 2016-10-14): 28 out of 378
Language: C++
/* UVa 12101 - Prime Path To build using Visual Studio 2012: cl -EHsc -O2 UVa_12101_Prime_Path.cpp */ #include <queue> #include <cstdio> #include <cstring> #include <cmath> using namespace std; const int n_min = 1000, n_max = 9999, nr_digits = '9' - '0' + 1; bool not_primes[n_max + 1]; // not_primes[i] is true if i is not a prime bool visited[n_max + 1]; void sieve_of_eratosthenes() { not_primes[0] = not_primes[1] = true; for (int i = 2, e = static_cast<int>(sqrt(static_cast<double>(n_max))); i <= e; i++) if (!not_primes[i]) { for (int j = i * i; j <= n_max; j += i) not_primes[j] = true; } } struct path { int p_; // prime int s_; // steps path(int p, int s) : p_(p), s_(s) {} }; void push_prime(queue<path>& q, int s, int d0, int d1, int d2, int d3) { int p = d0 * 1000 + d1 * 100 + d2 * 10 + d3; if (!not_primes[p] && !visited[p]) { visited[p] = true; q.push(path(p, s)); } } int bfs(int start, int end) { queue<path> q; memset(visited, 0, sizeof(visited)); visited[start] = true; q.push(path(start, 0)); while (!q.empty()) { path p = q.front(); q.pop(); if (p.p_ == end) return p.s_; int d0 = p.p_ / 1000, d1 = p.p_ % 1000 / 100, d2 = p.p_ % 100 / 10, d3 = p.p_ % 10, s = p.s_ + 1; for (int d = 1; d < nr_digits; d++) push_prime(q, s, d, d1, d2, d3); for (int d = 0; d < nr_digits; d++) push_prime(q, s, d0, d, d2, d3); for (int d = 0; d < nr_digits; d++) push_prime(q, s, d0, d1, d, d3); for (int d = 1; d < nr_digits; d += 2) push_prime(q, s, d0, d1, d2, d); } return -1; } int main() { sieve_of_eratosthenes(); int t; scanf("%d", &t); while (t--) { int start, end; scanf("%d %d", &start, &end); int steps = bfs(start, end); if (steps != -1) printf("%d\n", steps); else puts("Impossible"); } return 0; }
No comments:
Post a Comment