Browse Source

Nästan fungerande! xD

Jonatan Gezelius 6 năm trước cách đây
mục cha
commit
24b3fc4655
1 tập tin đã thay đổi với 189 bổ sung0 xóa
  1. 189 0
      p12101/p12101.cpp

+ 189 - 0
p12101/p12101.cpp

@@ -0,0 +1,189 @@
+#include <algorithm>
+#include <array>
+#include <iostream>
+#include <map>
+#include <utility>
+#include <vector>
+#include <iomanip>
+#include <sstream>
+#include <climits>
+#include <queue>
+
+using namespace std;
+
+typedef unsigned int nat;
+
+struct Edge;
+struct Node;
+
+struct Node
+{
+    Node(nat id) : id{id} {}
+
+    nat id;
+    vector<Edge*> edges;
+};
+
+struct Edge
+{
+    Edge(Node *a, Node *b) : a{a}, b{b}
+    {
+        a->edges.push_back(this);
+        b->edges.push_back(this);
+    }
+
+    Node *other(Node *curr) const
+    {
+        if(curr == a)
+            return b;
+
+        return a;
+    }
+
+    Node *a;
+    Node *b;
+};
+
+vector<bool> prime_sieve(nat upper_limit)
+{
+    ++upper_limit;
+    vector<bool> primes(upper_limit, true);
+    primes[0] = false;
+    primes[1] = false;
+    for(nat i = 2; i < upper_limit; ++i)
+    {
+        if(!primes[i])
+            continue;
+
+        for(nat j = 2*i; j < upper_limit; j += i)
+        {
+            primes[j] = false;
+        }
+    }
+
+    return primes;
+}
+
+
+
+bool neighbours(Node *a, Node *b)
+{
+    nat a_val = a->id, b_val = b->id;
+
+    nat diffs = 0;
+
+    for(nat i = 0; i < 4; ++i)
+    {
+        if((a_val% 10) != (b_val% 10))
+        {
+            ++diffs;
+        }
+        a_val /= 10;
+        b_val /= 10;
+    }
+
+    return (diffs == 1);
+}
+
+vector<Node*> make_graph(const vector<bool> &primes)
+{
+    vector<Node*> graph(primes.size());
+
+    for(nat i = 0; i < primes.size(); ++i)
+    {
+        graph[i] = new Node(i);
+    }
+
+    for(nat i = 1001; i < primes.size(); i += 2)
+    {
+        if(!primes[i])
+            continue;
+
+        for(nat j = i+2; j < primes.size(); j += 2)
+        {
+            if(neighbours(graph[i], graph[j]))
+            {
+                new Edge(graph[i], graph[j]);
+            }
+        }
+    }
+
+    return graph;
+}
+
+nat BFS_len(Node *source, Node *target)
+{
+    queue<pair<Node*, nat>> q;
+
+    q.push(make_pair(source, 0));
+
+    vector<bool> visited(10001, false);
+    visited[source->id] = true;
+
+    while(!q.empty())
+    {
+        Node *curr = q.front().first;
+        nat depth = q.front().second;
+        q.pop();
+
+        if(curr == target)
+        {
+            return depth;
+        }
+
+        for(Edge *e : curr->edges)
+        {
+            Node *other = e->other(curr);
+
+            if(!visited[other->id])
+            {
+                q.push(make_pair(other, depth+1));
+                visited[other->id] = true;
+            }
+        }
+    }
+
+    return (nat)-1;
+}
+
+int main()
+{
+    vector<bool> primes = prime_sieve(10000);
+    vector<Node*> graph = make_graph(primes);
+
+    nat num_tests, source, target;
+
+    /*
+    while(cin >> source)
+    {
+        for(auto e : graph[source]->edges)
+        {
+            cout << e->other(graph[source])->id << endl;
+        }
+    }
+
+    return 0;
+*/
+
+    cin >> num_tests;
+
+
+    for(nat i = 0; i < num_tests; ++i)
+    {
+        cin >> source >> target;
+
+        nat len = BFS_len(graph[source], graph[target]);
+
+        if(len == (nat)-1)
+        {
+            cout << "Impossible" << endl;
+        }
+        else
+        {
+            cout << len << endl;
+        }
+
+    }
+
+    return 0;
+}