1. 程式人生 > 實用技巧 >「賽後總結」AtCoder Beginner Contest 184

「賽後總結」AtCoder Beginner Contest 184

題意 & 題解

A.Determinant

題意:

給你 \(a,b,c,d\),計算 \(ad-ba\)

題解:

簽到題。

B.Quizzes

題意:

已有分數 \(X\),讀到 x 並且 \(X>0\)\(X-1\),讀到 o\(X + 1\)

題解:

簽到題。

C.Super Ryuma

題意:

給一個起點一個終點,可以往當前點所在在對角線或者曼哈頓距離為 \(3\) 以內的整點上跳,問最少幾步到達終點。

題解:

最多跳三次。

如果起點終點重合,共零次。如果終點在起點能跳到的電上,共一次。兩個點的對角線一定有個交點,如果是橫座標整數可以先跳到交點再往終點跳,還有其他跳的方式,不細說了,共兩次。如果不是整數可以先跳到終點的對角線附近,再跳到對角線上,再跳一次,共三次。

D.increment of coins

題意:

初始時有 \(a\) 個金幣,\(b\) 個銀幣,\(c\) 個銅幣,每次可以隨機取出一個 \(x\) 並放入兩個相同的 \(x\)。當出現 \(100\) 個相同的幣時停止,問操作次數的期望。

題解:

\(f_{i,j,k}\) 表示 \(i\) 個金幣,\(j\) 個銀幣,\(k\) 個銅幣到結束的操作次數的期望。

下一步可以到 \(f_{i+1,j,k}\)\(f_{i,j + 1,k}\)\(f_{i,j,k + 1}\) 三種狀態。

\(f_{i,j,k} = (f_{i+1,j,k}+1)\times\frac{i}{i+j+kj} + (f_{i,j+1,k}+1)\times\frac{j}{i+j+kj}+(f_{i,j,k+1}+1)\times\frac{k}{i+j+kj}\)

個人感覺記憶化搜尋比較好寫。

E.Third Avenue

題意:

一個地圖,可以向上下左右走,相同的小寫字母可以互相傳送,每一個操作都要一秒時間,問從起點到終點要耗費的最短時間。

題解:

字母只會在第一次遇到時進行傳送,所以直接寬搜。

F.Programming Contest

題意:

給定 \(n\) 個數以及一個 \(t\),你要找到若干數的和使它最大並且不超過 \(t\)

題解:

\(n \le 40\),用折半搜尋搜出前 \(20\) 個數和後 \(20\) 個數的選法之後用二分進行配對。

Code

A.Determinant

#include <cstdio>
#include <iostream>

int main() {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    std::cout << a * d - b * c << '\n';
    return 0;
}

B.Quizzes

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>

int n, x;
std::string s;

int main() {
    std::cin >> n >> x >> s;
    for (int i = 0; i < n; ++i) {
        if (s[i] == 'o') ++x;
        if (s[i] == 'x' && x) --x;
    }
    std::cout << x << '\n';
    return 0;
}

C.Super Ryuma

#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>

long long r1, c1, r2, c2;

int main() {
    std::cin >> r1 >> c1 >> r2 >> c2;
    if (r1 == r2 && c1 == c2) return puts("0"), 0;
    if (r1 + c1 == r2 + c2 || r1 - c1 == r2 - c2 || abs(r1 - r2) + abs(c1 - c2) <= 3) return puts("1"), 0;
    bool flag = false;
    if ((r2 + c2 + r1 - c1) % 2 == 0 || (r1 + c1 + r2 - c2) % 2 == 0) return puts("2"), 0;
    for (int i = r1 - 3; i <= r1 + 3; ++i) {
        for (int j = c1 - 3; j <= c1 + 3; ++j) {
            if (abs(r1 - i) + abs(c1 - j) > 3) continue;
            if (i + j == r2 + c2 || i - j == r2 - c2 || abs(i - r2) + abs(j - c2) <= 3) flag = true;
        }            
    }
    for (int i = r2 - 3; i <= r2 + 3; ++i) {
        for (int j = c2 - 3; j <= c2 + 3; ++j) {
            if (abs(r2 - i) + abs(c2 - j) > 3) continue;
            if (i + j == r1 + c1 || i - j == r1 - c1 || abs(i - r1) + abs(j - c1) <= 3) flag = true;
        }
    }
    if (flag) return puts("2"), 0;
    return puts("3"), 0;
}

D.increment of coins

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 101

int a, b, c;
double f[M][M][M];

double dfs(int x, int y, int z) {
    if (x >= 100 || y >= 100 || z >= 100) return 0;
    if (f[x][y][z] != -1) return f[x][y][z];
    f[x][y][z] = (dfs(x + 1, y, z) + 1) * ((x * 1.0) / (1.0 * (x + y + z)));
    f[x][y][z] += (dfs(x, y + 1, z) + 1) * ((y * 1.0) / (1.0 * (x + y + z)));
    f[x][y][z] += (dfs(x, y, z + 1) + 1) * ((z * 1.0) / (1.0 * (x + y + z)));
    return f[x][y][z];
}

int main() {
    for (int i = 0; i <= 100; ++i) {
        for (int j = 0; j <= 100; ++j) {
            for (int k = 0; k <= 100; ++k) {
                f[i][j][k] = -1;
            }
        }
    }
    std::cin >> a >> b >> c;
    printf("%.9lf\n", dfs(a, b, c));
    return 0;
}

E.Third Avenue

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#define M 2001
typedef std::pair<int, int> pii;

std::queue<pii> q;
std::vector<pii> V[27];
std::string map[M];
int n, m, a, b, d[M][M];
bool vis[M][M], used[M], f;
int dx[5] = {0, 1, -1, 0, 0};
int dy[5] = {0, 0, 0, 1, -1};

void bfs(int sx, int sy) {
    q.push(std::make_pair(sx, sy));
    d[sx][sy] = 0, vis[sx][sy] = true;
    while (!q.empty()) {
        int x = q.front().first, y = q.front().second; q.pop();
        if (map[x][y] == 'G') { f = 1, printf("%d\n", d[x][y]); return; }
        for (int i = 1; i <= 4; ++i) {
            int x_ = x + dx[i], y_ = y + dy[i];
            if (x_ <= 0 || x_ > n || y_ < 0 || y_ >= m) continue;
            if (map[x][y] == '#' || vis[x_][y_]) continue;
            vis[x_][y_] = true, d[x_][y_] = d[x][y] + 1;
            q.push(std::make_pair(x_, y_));
        }
        if (map[x][y] < 'a' || map[x][y] > 'z' || used[map[x][y] - 'a']) continue;
        used[map[x][y] - 'a'] = true;
        for (int i = 0; i < V[map[x][y] - 'a'].size(); ++i) {
            int x_ = V[map[x][y] - 'a'][i].first, y_ = V[map[x][y] - 'a'][i].second;
            if (vis[x_][y_]) continue;
            vis[x_][y_] = true, d[x_][y_] = d[x][y] + 1;
            q.push(std::make_pair(x_, y_));
        }
    }
}

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) std::cin >> map[i];
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (map[i][j] == 'S') a = i, b = j;
            if (map[i][j] >= 'a' && map[i][j] <= 'z') {
                V[map[i][j] - 'a'].push_back(std::make_pair(i, j));
            }
        }
    }
    bfs(a, b);
    if (!f) puts("-1");
    return 0;
}

F.Programming Contest

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 21

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int n, m, t, c1, c2, a[M], b[M];
int ans, ans1[1 << M], ans2[1 << M];

void dfs1(int step, int now) {
    if (now > t) return;
    if (step > n) { ans1[++c1] = now; return; }
    for (int i = 0; i <= 1; ++i) {
        if (i == 1) dfs1(step + 1, now + a[step]);
        if (i == 0) dfs1(step + 1, now);
    }
}

void dfs2(int step, int now) {
    if (now > t) return;
    if (step > m) { ans2[++c2] = now; return; }
    for (int i = 0; i <= 1; ++i) {
        if (i == 1) dfs2(step + 1, now + b[step]);
        if (i == 0) dfs2(step + 1, now);
    }
}

int main() {
    scanf("%d %d", &n, &t);
    m = n - 20, n = min(n, 20);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    for (int i = 1; i <= m; ++i) scanf("%d", &b[i]);
    dfs1(1, 0);
    if (m > 0) dfs2(1, 0);
    std::sort(ans1, ans1 + c1 + 1);
    std::sort(ans2, ans2 + c2 + 1);
    for (int i = 0; i <= c1; ++i) {
        int temp = t - ans1[i];
        int pos = std::lower_bound(ans2, ans2 + c2 + 1, temp) - ans2;
        if (pos == c2 + 1 || ans2[pos] > temp) --pos;
        ans = max(ans, ans1[i] + ans2[pos]);
    }
    std::cout << ans << '\n';
    return 0;
}

rating & 總結