結果

問題 No.2287 ++ -- *=a /=a
ユーザー みここみここ
提出日時 2023-04-14 21:08:34
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
RE  
実行時間 -
コード長 4,114 bytes
コンパイル時間 1,383 ms
コンパイル使用メモリ 106,808 KB
実行使用メモリ 5,248 KB
最終ジャッジ日時 2024-11-17 19:16:08
合計ジャッジ時間 3,725 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 3 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 3 ms
5,248 KB
testcase_04 AC 2 ms
5,248 KB
testcase_05 AC 2 ms
5,248 KB
testcase_06 RE -
testcase_07 WA -
testcase_08 WA -
testcase_09 AC 86 ms
5,248 KB
testcase_10 AC 65 ms
5,248 KB
testcase_11 AC 59 ms
5,248 KB
testcase_12 AC 51 ms
5,248 KB
testcase_13 AC 49 ms
5,248 KB
testcase_14 AC 46 ms
5,248 KB
testcase_15 AC 45 ms
5,248 KB
testcase_16 AC 45 ms
5,248 KB
testcase_17 AC 45 ms
5,248 KB
testcase_18 RE -
testcase_19 WA -
testcase_20 RE -
testcase_21 WA -
testcase_22 RE -
testcase_23 WA -
testcase_24 RE -
testcase_25 WA -
testcase_26 WA -
testcase_27 RE -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <cassert>
#include <queue>
#include <map>
using namespace std;

template <typename T = int>
struct Graph
{
public:
    using value_type = T;

    struct Edge
    {
        int from, to;
        T cost;
        int id;

        operator int() const
        {
            return to;
        }
    };

    Graph() {}

    Graph(int n) : n(n), m(0), g(n) {}

    void add_directed_edge(int from, int to, T cost = 1)
    {
        assert(0 <= from && from < n);
        assert(0 <= to && to < n);
        g[from].push_back((Edge){from, to, cost, m++});
    }

    void add_undirected_edge(int from, int to, T cost = 1)
    {
        assert(0 <= from && from < n);
        assert(0 <= to && to < n);
        g[from].push_back((Edge){from, to, cost, m});
        g[to].push_back((Edge){to, from, cost, m++});
    }

    int size()
    {
        return n;
    }

    int edge_size()
    {
        return m;
    }

    inline const std::vector<Edge> &operator[](const int &u) const
    {
        return g[u];
    }

    inline std::vector<Edge> &operator[](const int &u)
    {
        return g[u];
    }

private:
    int n, m;
    std::vector<std::vector<Edge>> g;
};

template <typename GRAPH>
std::vector<typename GRAPH::value_type> dijkstra(GRAPH &g, int s)
{
    using T = typename GRAPH::value_type;
    using P = std::pair<T, int>;
    int n = g.size();
    assert(s >= 0 && s < n);
    std::vector<T> d(n, -1);
    std::priority_queue<P, std::vector<P>, std::greater<P>> que;
    d[s] = 0;
    que.push(P(0, s));
    while (que.size())
    {
        auto [dist, u] = que.top();
        que.pop();
        if (d[u] < dist)
        {
            continue;
        }
        for (auto e : g[u])
        {
            int v = e.to;
            if (d[v] == -1 || d[v] > d[u] + e.cost)
            {
                d[v] = d[u] + e.cost;
                que.push(P(d[v], v));
            }
        }
    }
    return d;
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int x, y, a;
        cin >> x >> y >> a;
        int z = y;
        int p = x, q = y;
        Graph<int> g(100);
        map<int, int> mp;
        int r[20];
        int k = 0;
        if (!mp.count(x))
        {
            r[k] = x;
            mp[x] = k++;
        }
        if (!mp.count(y))
        {
            r[k] = y;
            mp[y] = k++;
        }
        if (!mp.count(y + 1))
        {
            r[k] = y + 1;
            mp[y + 1] = k++;
        }
        while (x || y)
        {
            if (x <= y)
            {
                g.add_directed_edge(mp[x], mp[y], y - x);
                y /= a;
                if (!mp.count(y))
                {
                    r[k] = y;
                    mp[y] = k++;
                }
                if (!mp.count(y + 1))
                {
                    r[k] = y + 1;
                    mp[y + 1] = k++;
                }
            }
            else
            {
                g.add_directed_edge(mp[x], mp[y + 1], x - (y + 1));
                if (!mp.count(x / a))
                {
                    r[k] = x / a;
                    mp[x / a] = k++;
                }
                g.add_directed_edge(mp[x], mp[x / a], 1);
                x /= a;
            }
        }
        while (true)
        {
            int w = z / a;
            g.add_directed_edge(mp[z], mp[z + 1], 1);
            g.add_directed_edge(mp[z + 1], mp[z], 1);
            g.add_directed_edge(mp[w], mp[z], z - w * a + 1);
            g.add_directed_edge(mp[w + 1], mp[z + 1], (w + 1) * a - (z + 1) + 1);
            if (z >= w + a)
            {
                g.add_directed_edge(mp[z], mp[w + 1], z - (w + 1));
                g.add_directed_edge(mp[w + 1], mp[z], z - (w + 1));
            }
            if (z >= (w / a + 1) * a)
            {
                g.add_directed_edge(mp[w / a + 1], mp[z], z - (w / a + 1) * a + 1);
            }
            if (!z)
            {
                break;
            }
            z = w;
        }
        vector<int> d = dijkstra(g, mp[p]);
        cout << d[mp[q]] << endl;
    }
}
0