"2019 Jizhong training Day9" problem-solving report

\ (Flag \) : Uniform blog format (cushions)

T1, take the plaid

A \ (n \ times m \ ( 4 \ leq n, m \ leq 500) \) matrix, the matrix there are four elements: walls ( "#"), space area ( ''. "), The starting point (" C "), end point (" F ").
there are transmitted gun operations: shot in any direction of four directions, there will be a portal in the first wall encountered, only the presence of two simultaneously transmitted door, if already there are two portals, the portal will appear first shot of the disappearance, the operation does not consume time
to move from the starting point, each can be moved to an adjacent grid, or have in the portal wall adjacent grid by a portal (portal must exist two), moved to another transfer gate adjacent to the grid, both operations can not be moved to the wall and consumes a unit time
from start to finish at least several time-consuming units.
guarantee edge of the map is a circle wall.

\(Sol\)

Transfer gun use: four walls can hit in the recent fight side and the other side, the side that recently went through the portal.
Shortest can be.

Time complexity \ (O \ Big (nm \ log_2 (nm) \ Big) \) .

\(Source\)

//#pragma GCC Optmize(2)
//#pragma GCC Optmize(3, "Ofast", "inline")
#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 = 505;

char mp[N][N];

struct link {
    int l, r, u, d;
} nxt[N][N];

int n, m, d[N][N];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
bool vis[N][N];
typedef std::pair<int, int> pii;
typedef std::pair<int, pii> pip;

int dijkstra() {
    std::priority_queue<pip> q;
    int ex, ey;
    memset(d, 0x3f, sizeof(d));
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j) {
            if (mp[i][j] == 'C')
                q.push(pip(0, pii(i, j))), d[i][j] = 0;
            if (mp[i][j] == 'F')
                ex = i, ey = j;
        }
    while (!q.empty()) {
        int nx = q.top().second.first, ny = q.top().second.second, tx, ty, tmp; q.pop();
        if (vis[nx][ny])
            continue;
        vis[nx][ny] = 1;
        if (nx == ex && ny == ey)
            return d[nx][ny];
        for (int i = 0; i < 4; ++i) {
            tx = nx + dx[i], ty = ny + dy[i];
            if (mp[tx][ty] == '#' || d[nx][ny] + 1 >= d[tx][ty])
                continue;
            d[tx][ty] = d[nx][ny] + 1;
            q.push(pip(-d[tx][ty], pii(tx, ty)));
        }
        tmp = ny - nxt[nx][ny].l;
        chk_min(tmp, nx - nxt[nx][ny].u);
        chk_min(tmp, nxt[nx][ny].r - ny);
        chk_min(tmp, nxt[nx][ny].d - nx);
        ++tmp;

        tx = nx, ty = nxt[nx][ny].l;
        if (ny - ty > tmp && d[tx][ty] > d[nx][ny] + tmp)
            d[tx][ty] = d[nx][ny] + tmp, q.push(pip(-d[tx][ty], pii(tx, ty)));
        tx = nx, ty = nxt[nx][ny].r;
        if (ty - ny > tmp && d[tx][ty] > d[nx][ny] + tmp)
            d[tx][ty] = d[nx][ny] + tmp, q.push(pip(-d[tx][ty], pii(tx, ty)));
        tx = nxt[nx][ny].u, ty = ny;
        if (nx - tx > tmp && d[tx][ty] > d[nx][ny] + tmp)
            d[tx][ty] = d[nx][ny] + tmp, q.push(pip(-d[tx][ty], pii(tx, ty)));
        tx = nxt[nx][ny].d, ty = ny;
        if (tx - nx > tmp && d[tx][ty] > d[nx][ny] + tmp)
            d[tx][ty] = d[nx][ny] + tmp, q.push(pip(-d[tx][ty], pii(tx, ty)));
    }
    return -1;
}

int main() {
    //freopen("in", "r", stdin);
    freopen("cell.in", "r", stdin);
    freopen("cell.out", "w", stdout);
    n = in(), m = in();
    memset(nxt, -1, sizeof(nxt));
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            while (mp[i][j] != '.' && mp[i][j] != 'C' && mp[i][j] != 'F' && mp[i][j] != '#')
                mp[i][j] = getchar();
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j) {
            if (mp[i][j] == '#')
                continue;
            if (mp[i - 1][j] != '#')
                nxt[i][j].u = nxt[i - 1][j].u;
            else
                nxt[i][j].u = i;
            if (mp[i][j - 1] != '#')
                nxt[i][j].l = nxt[i][j - 1].l;
            else
                nxt[i][j].l = j;
        }
    for (int i = n; i; --i)
        for (int j = m; j; --j) {
            if (mp[i][j] == '#')
                continue;
            if (mp[i + 1][j] != '#')
                nxt[i][j].d = nxt[i + 1][j].d;
            else
                nxt[i][j].d = i;
            if (mp[i][j + 1] != '#')
                nxt[i][j].r = nxt[i][j + 1].r;
            else
                nxt[i][j].r = j;
        }
    int res = dijkstra();
    if (!~res)
        puts("no");
    else
        printf("%d\n", res);
    return 0;
}

T2, the number of twist

To have a \ (key \ (1 \ leq key \ leq 10 ^ {18}) \) is the key, \ (Val \ (. 1 \ Leq Val \ ^ 10 Leq. 6) \) is the weight value \ (the BST \) , each node denoted \ (sUM \) is in its subtree rooted at \ (Val \) sum. Given \ (n \ (1 \ leq n \ leq 300) \) points \ (Key \) and \ (Val \) , the need to ensure two arbitrary points on an edge of the tree \ (Key \) is not prime, seek \ (sUM \) the sum of the maximum value. If there is no legal form of a tree, output \ (--1 \) .

\(Sol\)

Consider interval \ (DP \) , the sequence now press \ (Key \) sorting, denoted \ (f_ {i, j, 0/1} \) representing the interval \ ([i, j] \ ) can be used as \ (I 1 (represented by 0) / i + 1 (represented by 1) \) - maximum of subtrees \ (SUM \) and, to transfer violence.
In \ (f_ {i, j, 0} \) Example (without considering the boundary):
\ [F_ {I, J,} = 0 \ = I + K max_ {^ {J}. 1 -. 1} \ {F_ {i, k - 1,1} +
f_ {k + 1, j, 0} + sum [i, j] \} \] time complexity \ (O (n-^. 3) \) .

\(Source\)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
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;
}
long long lin() {
    long long 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 = 305;

int n, sum[N], id[N];
long long key[N], tmp[N], f[N][N][2];
bool mp[N][N];

long long gcd(long long _, long long __) {
    return __ ? gcd(__, _ % __) : _;
}

inline bool cmp(const int &i, const int j) {
    return key[i] < key[j];
}

void init() {
    for (int i = 1; i <= n; ++i)
        id[i] = i;
    std::sort(id + 1, id + 1 + n, cmp);
    for (int i = 1; i <= n; ++i)
        tmp[i] = key[id[i]];
    for (int i = 1; i <= n; ++i)
        key[i] = tmp[i];
    for (int i = 1; i <= n; ++i)
        tmp[i] = sum[id[i]];
    for (int i = 1; i <= n; ++i)
        sum[i] = sum[i - 1] + tmp[i];
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j <= n; ++j)
            mp[i][j] = gcd(key[i], key[j]) > 1;
}

int main() {
    //freopen("in", "r", stdin);
    freopen("tree.in", "r", stdin);
    freopen("tree.out", "w", stdout);
    n = in();
    for (int i = 1; i <= n; ++i)
        key[i] = lin(), sum[i] = in();
    init(); 
    for (int i = 1; i <= n; ++i) {
        if (mp[i - 1][i])
            f[i][i][0] = sum[i] - sum[i - 1];
        if (mp[i][i + 1])
            f[i][i][1] = sum[i] - sum[i - 1];
    }
    for (int len = 2; len <= n; ++len) {
        for (int i = 1; i + len - 1 <= n; ++i) {
            int j = i + len - 1;
            if (f[i + 1][j][0]) {
                if (mp[i - 1][i])
                    chk_max(f[i][j][0], f[i + 1][j][0] + sum[j] - sum[i - 1]);
                if (mp[i][j + 1])
                    chk_max(f[i][j][1], f[i + 1][j][0] + sum[j] - sum[i - 1]);
            }
            if (f[i][j - 1][1]) {
                if (mp[i - 1][j])
                    chk_max(f[i][j][0], f[i][j - 1][1] + sum[j] - sum[i - 1]);
                if (mp[j][j + 1])
                    chk_max(f[i][j][1], f[i][j - 1][1] + sum[j] - sum[i - 1]);
            }
            for (int k = i + 1; k < j; ++k) {
                if (mp[i - 1][k] && f[i][k - 1][1] && f[k + 1][j][0])
                    chk_max(f[i][j][0], f[i][k - 1][1] + f[k + 1][j][0] + sum[j] - sum[i - 1]);
                if (mp[k][j + 1] && f[i][k - 1][1] && f[k + 1][j][0])
                    chk_max(f[i][j][1], f[i][k - 1][1] + f[k + 1][j][0] + sum[j] - sum[i - 1]);
            }
        }
    }
    if (f[1][n][0])
        printf("%lld\n", f[1][n][0]);
    else
        puts("-1");
    return 0;
}

T3, sub-segment rotation

Given a length \ (n-\) arranged \ (\ {a_i \} \) , can flip a sub interval, the request flip the section \ (I \) number of the positions is equal to \ (I \) of the largest number.

\(Sol\)

Flip range of about endpoint must have a cause contribution, consider enumerated about endpoints and quickly calculate the contribution flip interval.
Note that for any of a number of unordered \ ((I, a_i) \) , and it is only the rotation center equal to not more than it contributes to a shorter interval, it is possible to put all the rotation center equal to the random number together, according to the length of from small to large enumeration to meet the demand.

Time complexity \ (O (n-) \) .

Source:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
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;

int n, a[N], p[N], pre[N];

typedef std::pair<int, int> pii;
std::vector<pii> s[N << 1];

int main() {
    //freopen("in", "r", stdin);
    freopen("rotate.in", "r", stdin);
    freopen("rotate.out", "w", stdout);
    n = in();
    for (int i = 1; i <= n; ++i)
        a[i] = in(), p[a[i]] = i, pre[i] = pre[i - 1] + (a[i] == i);
    for (int i = 1; i <= n; ++i) {
        if (a[i] <= i)
            s[i + a[i]].push_back(pii(i, a[i]));
        if (p[i] < i)
            s[i + p[i]].push_back(pii(i, p[i]));
    }
    int res = pre[n];
    for (int i = 1; i <= n + n; ++i)
        for (unsigned j = 0; j < s[i].size(); ++j)
            chk_max(res, (int)j + 1 + pre[s[i][j].second - 1] + pre[n] - pre[s[i][j].first]);
    printf("%d\n", res);
    return 0;
}

Guess you like

Origin www.cnblogs.com/15owzLy1-yiylcy/p/11329391.html