CodeCraft-21 and Codeforces Round #711 (Div. 2) A~C 个人题解

补题链接:Here

1498A. GCD Sum

题意:给定一个 gcdSum 操作:\(gcdSum(762) = gcd(762,7 + 6 + 2) = gcd(762,15) = 3\)

请问要执行多少次 gcdSum 才能使结果不为 \(1\)

输出最后的 \(n\)

思路:按题意来,因为数据范围在 1e18 在执行 gcdSum 时比较快

using ll = long long;
ll gcd(ll x, ll y) { return y == 0 ? x : gcd(y, x % y); }
ll getSum(ll n) {
    ll s = 0;
    while (n) {
        s += n % 10, n /= 10;
    }
    return s;
}
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    int _;
    for (cin >> _; _--;) {
        ll n;
        cin >> n;
        while (gcd(n, getSum(n)) == 1) n++;
        cout << n << "\n";
    }
    return 0;
}

1498B. Box Fitting

题意:在一个被限定了宽度的盒子中给一些长度为 \(2^x\) 高度为 \(1\) 的长方块,请问怎么排放才能使最终高度最小

思路:先利用 map 存储各个长度的值,然后二分找到在该行中最大的一块然后填充。

这里建议看代码理解

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    int _;
    for (cin >> _; _--;) {
        int n, w;
        cin >> n >> w;
        map<int, int> mp;
        for (int i = 0, x; i < n; ++i) {
            cin >> x;
            mp[x]++;
        }
        int ans = 1, cur = w;
        while (mp.size()) {
            if (mp.begin()->first > cur) {
                ++ans, cur = w;
            }
            auto it = prev(mp.upper_bound(cur));
            assert(it->first <= cur);
            cur -= it->first;
            if (--(it->second) == 0) mp.erase(it);
        }
        cout << ans << "\n";
    }
    return 0;
}

1498C. Planar Reflections

DP优化 + 模拟

题意:给定一个可以穿越墙体的微观粒子(寿命为 \(k\)),但是每穿越一次墙体会产生一个反向寿命为 \(k - 1\) 的粒子。

请问最终共有多少个粒子?

思路:模拟变化过程,然后开DP数组存储已经计算过的即可,写的时候要注意细节,比如什么时候 \(k - 1\) 或者 \(1 - dir\) 方向变化

const int mod = 1e9 + 7;
int n, k;
int dp[1010][1010][2];
int solve(int cur, int k, int dir) {
    if (k == 1) return 1;
    // 非 -1 说明已经计算过了
    if (dp[cur][k][dir] != -1) return dp[cur][k][dir];
    int ans = 2;  // 本身和穿过墙的复制体
    if (dir == 1) {
        if (cur < n) ans += solve(cur + 1, k, dir) - 1;
        ans %= mod;
        if (cur > 1) ans += solve(cur - 1, k - 1, 1 - dir) - 1;
        ans %= mod;
        dp[cur][k][dir] = ans;
    } else {
        if (cur > 1) ans += solve(cur - 1, k, dir) - 1;
        ans %= mod;
        if (cur < n) ans += solve(cur + 1, k - 1, 1 - dir) - 1;
        ans %= mod;
        dp[cur][k][dir] = ans;
    }
    return ans;
}
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    int _;
    for (cin >> _; _--;) {
        cin >> n >> k;
        memset(dp, -1, sizeof dp);
        cout << solve(1, k, 1) << '\n';
    }
    return 0;
}

在学习高榜大佬的代码时候发现的一种解法,Orz...

#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
int X[1001], Y[1001], n, k, K, R, val;
signed main() {
    for (cin >> n; cin >> n >> k;) {
        for (R = 0; R <= n; R++) X[R] = Y[R] = 0;
        for (K = 2; K <= k; K++) {
            for (R = n; R >= 0; R--) X[R] = (R + Y[n - R]) % mod;
            val = 0;
            for (R = n - 1; R >= 0; R--) Y[R] = (val += X[R]) %= mod;
        }
        cout << (1 + X[n]) % mod << ' ';
    }
}
posted @ 2021-03-30 16:05  Koshkaaa  阅读(135)  评论(0编辑  收藏  举报