「2019 JizhongトレーニングDay10」問題解決レポート

T1、数学

二つのベクトルが与え\(\ VEC {A}、\ VEC {B} \) 整数X、Yの組を取得するように\(| X \ VEC + Y \ VEC B | \) 最小出力\(| ^ 2 \ | X \ VEC + Y \ VEC b)の最小値。

\(ソル\)

論文のトピック。
ジンビン「アプリケーションユークリッドアルゴリズムの
時間複雑\(O(すぐに)\)

\(出典\)

#include <cstdio>
#include <cstring>
#include <algorithm>

void exgcd(long long x_1, long long y_1, long long x_2, long long y_2, long long &a, long long &b) {
    long long dp = x_1 * x_2 + y_1 * y_2, mod_a = x_1 * x_1 + y_1 * y_1, mod_b = x_2 * x_2 + y_2 * y_2;
    if (dp < 0) {
        exgcd(-x_1, -y_1, x_2, y_2, a, b);
        a = -a;
        return ;
    }
    if (4 * dp * dp <= mod_a * mod_b || dp == 0) {
        if (mod_a < mod_b)
            a = 1, b = 0;
        else
            b = 1, a = 0;
        return ;
    }
    bool flag = 0;
    if (mod_a > mod_b) {
        std::swap(x_1, x_2);
        std::swap(y_1, y_2);
        std::swap(mod_a, mod_b);
        flag = 1;
    }
    long long k = dp / mod_a;
    if (dp - k * mod_a > (k + 1) * mod_a - dp || !k)
        ++k;
    exgcd(x_1, y_1, x_2 - k * x_1, y_2 - k * y_1, a, b);
    a -= k * b;
    if (flag)
        std::swap(a, b);
}

int main() {
    //freopen("in", "r", stdin);
    freopen("math.in", "r", stdin);
    freopen("math.out", "w", stdout);
    long long x_1, y_1, x_2, y_2, a, b;
    while (~scanf("%lld %lld %lld %lld", &x_1, &y_1, &x_2, &y_2)) {
        a = b = 0;
        exgcd(x_1, y_1, x_2, y_2, a, b);
        printf("%lld\n", (a * x_1 + b * x_2) * (a * x_1 + b * x_2) + (a * y_1 + b * y_2) * (a * y_1 + b * y_2));
    }
    return 0;
}

宝物を掘りT2、

得られる(時間\回N \回\を M \(1つの\当量のH、N、Mの\の当量10)\) で各立方体、\(K_I \)宝物は、宝物は宝物を得ることができる位置に到達します。取るためにグリッドを移動\(A_ {I、J、 K}を\) グリッドの後にグリッドを考慮に移動のコストになる(0 \)\、唯一同じ層または次の層へ移動することができます。最初は最小コストを求めて、すべての宝物を得るために、(地面に移動するの費用をかけずに)接地してください。

\(ソル\)

\({I、J、F_ ST} \)は、 DIG意味\((I、J)\)宝状態含む、\(ST \)最低。
、層の間の移行中の1つの以上の時間の最小スタイナー木を求める((i、j)を\ \を ) 宝物、プラスの層のコスト\(F_ {I、J、 U} \) することができ、(\ U \)は、完全な作品を表します。
時間複雑度\(O(H \ ^ K. 3(G +のNM(NM)))\) \(G(nm)は\)最も短いの複雑さを表します。

\(出典\)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
int in() {
    int x = 0; char c = getchar(); bool f = 0;
    while (c < '0' || c > '9')
        f |= c == '-', c = getchar();
    while (c >= '0' && c <= '9')
        x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 11, inf = 0x3f3f3f3f;

int h, n, m, a[N][N][N], f[N][N][(1 << N) + 1], res;

typedef std::pair<int, int> pii;
std::vector<pii> s[N];
bool vis[N][N];
struct node {
    int x, y;
} ;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
std::queue<node> q;

int main() {
    //freopen("in", "r", stdin);
    freopen("treasure.in", "r", stdin);
    freopen("treasure.out", "w", stdout);
    h = in(), n = in(), m = in();
    for (int i = 1; i <= h; ++i)
        for (int j = 1; j <= n; ++j)
            for (int k = 1; k <= m; ++k)
                a[i][j][k] = in();
    for (int i = 1; i <= h; ++i)
        for (int k = in(), x, y; k; k--) {
            x = in(), y = in();
            s[i].push_back(pii(x, y));
        }

    for (int now = 1; now <= h; ++now) {
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j) {
                f[i][j][1] = f[i][j][(1 << (s[now - 1].size() + 1)) - 1] + a[now][i][j];
                for (int st = 2; st < (1 << (s[now].size() + 1)); ++st)
                    f[i][j][st] = inf;
            }
        for (unsigned i = 0; i < s[now].size(); ++i) {
            f[s[now][i].first][s[now][i].second][1 << (i + 1)] = a[now][s[now][i].first][s[now][i].second];
        }
        for (int st = 1; st < (1 << (s[now].size() + 1)); ++st) {
            for (int i = 1; i <= n; ++i)
                for (int j = 1; j <= m; ++j) {
                    for (int s1 = (st - 1) & st; s1; s1 = (s1 - 1) & st)
                        chk_min(f[i][j][st], f[i][j][s1] + f[i][j][st ^ s1] - a[now][i][j]);
                    if (f[i][j][st] < inf)
                        q.push((node){i, j}), vis[i][j] = 1;
                }
            while (!q.empty()) {
                node u = q.front(); q.pop();
                vis[u.x][u.y] = 0;
                for (int i = 0; i < 4; ++i) {
                    node v = u;
                    v.x += dx[i], v.y += dy[i];
                    if (v.x < 0 || v.x > n || v.y < 0 || v.y > m)
                        continue;
                    if (f[u.x][u.y][st] + a[now][v.x][v.y] < f[v.x][v.y][st])
                        f[v.x][v.y][st] = f[u.x][u.y][st] + a[now][v.x][v.y], q.push(v), vis[v.x][v.y] = 1;
                }
            }
        }
    }

    res = inf;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            chk_min(res, f[i][j][(1 << (s[h].size() + 1)) - 1]);
    printf("%d\n", res);
    return 0;
}

T3、理想的な街

いくつかの黒通信4ブラック格子、4つの通信白い正方形を確保するために、無限格子の格子(格子残り白)を得ます。格子ブラック(4つの通信経路ブラックグリッド)の異なる不規則格子点間の最短経路を求めるの数。

\(ソル\)

すべての単純パスと木のエッジの数\(\ _ {SUM(U、V)\} size_u Eで\タイムズsize_v \) すなわち、各辺の計算投稿)。
この問題に問題がエッジと隣接する格子間、ツリーに変換さを考慮すると、4色のグリッドとの通信を確保します。
実線は、グリッド点に押し込まれ、その左右の交差部と、前または次のライン部がヌル点もエッジではありません。
ツリーに従ってこのように処理されたリングの通信白、ビューはありませんので、同じ列及び行は、4つの格子で処理するので、プロセス。

時間複雑\(O(N \ + N-N-log_2)\)

\(出典\)

//#pragma GCC optimize(2)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
int in() {
    int x = 0; char c = getchar(); bool f = 0;
    while (c < '0' || c > '9')
        f |= c == '-', c = getchar();
    while (c >= '0' && c <= '9')
        x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 1e5 + 5, mod = 1e9;

int n, res;

struct node {
    int x, y;
} a[N], b[N];
inline bool cmpx(const node &i, const node &j) {
    return i.x == j.x ? i.y < j.y : i.x < j.x;
}
inline bool cmpy(const node &i, const node &j) {
    return i.y == j.y ? i.x < j.x : i.y < j.y;
}

struct edge {
    int next, to;
} e[N];
int ecnt, head[N], siz[N], node_tot;

inline void jb(const int u, const int v) {
    e[++ecnt] = (edge){head[u], v}, head[u] = ecnt;
    e[++ecnt] = (edge){head[v], u}, head[v] = ecnt;
}

void dfs(const int u, const int fa) {
    siz[u] = b[u].y - b[u].x + 1;
    for (int i = head[u]; i; i = e[i].next) {
        int v = e[i].to;
        if (v == fa)
            continue;
        dfs(v, u);
        siz[u] += siz[v];
        res += 1ll * siz[v] * (n - siz[v]) % mod;
        if (res >= mod)
            res -= mod;
    }
}

int main() {
    //freopen("in", "r", stdin);
    freopen("city.in", "r", stdin);
    freopen("city.out", "w", stdout);
    n = in();
    for (int i = 1; i <= n; ++i)
        a[i] = (node){in(), in()};

    ecnt = 1, node_tot = 0;
    std::sort(a + 1, a + 1 + n, cmpx);
    for (int i = 1, j = 1, p = 0, t = 1; i <= n; i = ++j) {
        while (a[j + 1].x == a[j].x && a[j + 1].y == a[j].y + 1)
            ++j;
        b[++node_tot] = (node){a[i].y, a[j].y};
        if (p) {
            for (; p < t && b[p].y < b[node_tot].x; ++p);
            for (; p < t && b[p].y <= b[node_tot].y; ++p)
                jb (p, node_tot);
            if (p < t && b[p].x <= b[node_tot].y)
                jb (p, node_tot);
        }
        if (a[j + 1].x != a[j].x)
            p = t, t = node_tot + 1;
    }
    dfs(1, -1);

    ecnt = 1, node_tot = 0;
    memset(head, 0, sizeof(head));
    std::sort(a + 1, a + 1 + n, cmpy);
    for (int i = 1, j = 1, p = 0, t = 1; i <= n; i = ++j) {
        while (a[j + 1].y == a[j].y && a[j + 1].x == a[j].x + 1)
            ++j;
        b[++node_tot] = (node){a[i].x, a[j].x};
        if (p) {
            for (; p < t && b[p].y < b[node_tot].x; ++p);
            for (; p < t && b[p].y <= b[node_tot].y; ++p)
                jb (p, node_tot);
            if (p < t && b[p].x <= b[node_tot].y)
                jb (p, node_tot);
        }
        if (a[j + 1].y != a[j].y)
            p = t, t = node_tot + 1;
    }
    dfs(1, -1);

    printf("%d\n", res);
    return 0;
}

おすすめ

転載: www.cnblogs.com/15owzLy1-yiylcy/p/11334079.html