ABC 129 题解 | JorbanS

A - Airplane

题意 找出三数选两数最小相加和

复杂度 O(1)

#include 

using namespace std;

int main() {
    int p, q, r; cin >> p >> q >> r;
    int a = p + q;
    int b = q + r;
    int c = r + p;
    cout << min(a, min(b, c));
    return 0;
}

B - Balance

题意 在一列数中插一块板使得左边、右边数的和相差最小,求最小值

Tag 前缀和 后缀和

复杂度 O(n)

#include 
#include 

using namespace std;
const int N = 102;
int a[N], s[N], S[N];

int main() {
    int n; cin >> n;
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        s[i] = s[i - 1] + a[i];
    }
    for (int i = n; i >= 1; i --) {
        S[i] = S[i + 1] + a[i];
    }
    int res = 100;
    for (int i = 1; i <= n; i ++) {
        res = min(res, abs(s[i] - S[i + 1]));
    }
    cout << res << endl;
    return 0;
}

C - Typical Stairs

题意 走楼梯,但有些台阶破损

Tag dp

复杂度 O(n)

#include 

using namespace std;
const int N = 1e5 + 2, mod = 1e9 + 7;
int n, m;
int f[N];

int main() {
    cin >> n >> m;
    f[0] = f[1] = 1;
    while (m --) {
        int x; cin >> x;
        f[x] = -1;
    }
    for (int i = 2; i < N; i ++) {
        if (f[i] == -1) continue;
        f[i] = (max(0, f[i - 1]) + max(0, f[i - 2])) % mod;
    }
    cout << f[n] << endl;
    return 0;
}

D - Lamp

题意 一个矩形区域内有障碍物,找到一个点使得向上下左右四个方向衍生的距离和最大,输出最大覆盖的面积

复杂度 O(n^2)

#include 

using namespace std;
const int N = 2e3 + 2;
int h, w;
char s[N][N];
int ww[N][N], hh[N][N];

int main() {
    cin >> h >> w;
    for (int i = 0; i < h; i ++) cin >> s[i];
    for (int i = 0; i < h; i ++) {
        int idx = 0;
        for (int j = 0; j < w; j ++) {
            if (s[i][j] == '#') {
                for (int k = idx; k < j; k ++) ww[i][k] = j - idx;
                idx = j + 1;
            } else if (j == w - 1) {
                for (int k = idx; k < w; k ++) ww[i][k] = w - idx;
            }
        }
    }
    for (int i = 0; i < w; i ++) {
        int idx = 0;
        for (int j = 0; j < h; j ++) {
            if (s[j][i] == '#') {
                for (int k = idx; k < j; k ++) hh[k][i] = j - idx;
                idx = j + 1;
            } else if (j == h - 1) {
                for (int k = idx; k < h; k ++) hh[k][i] = h - idx;
            }
        }
    }
    int res = 0;
    for (int i = 0; i < h; i ++) {
        for (int j = 0; j < w; j ++) {
            res = max(res, hh[i][j] + ww[i][j]);
        }
    }
    cout << res - 1 << endl;
    return 0;
}

E - Sum Equals Xor

题意 二进制整数 L ,有多少个非负整数对 a b 满足 a + b = a ⊕ b ≤ L,答案 mod 1e9 + 7

Tag dp

复杂度 O(n)

因为异或算法无法产生新的 1,因此此题不存在进位情况

状态转移方程 f[i][0] 表示二进制数 a + bi 个数和 L 相同,f[i][1] 表示二进制数 a + bi 个数严格小于 L

  • a + bL 相等时

    • L 当前位为 0 时,a = 0, b = 0
    • L 当前位为 1 时,a = 1, b == 0a = 0, b = 1
  • a + b 严格小于 L

    • 前面已经严格小于 La = 1, b == 0a = 0, b = 1a = 0, b = 0
    • 从当前位置开始严格小于 L,当且仅当 L 当前位为 1 时,a = 0, b = 0

可以简化为 f0f1

#include 

using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;

int main() {
    char c;
    ll f0 = 1, f1 = 0;
    while (scanf("%c", &c) != EOF && (c == '0' || c == '1')) {
        f1 = f1 * 3 % mod;
        if (c == '1') f1 = (f0 + f1) % mod, f0 = f0 * 2 % mod;
    }
    cout << (f0 + f1) % mod << endl;
    return 0;
}

你可能感兴趣的:(OI,题解,算法,c++)