CodeForces 1042

141 阅读1分钟

CodeForces 1042. C. Array Product

题目链接

题目

给定一个长度为 n 的数组 a,求一个长度为 n 的数组 b,使得 b[i]是除了 a[i]之外的所有元素的乘积。

如果有多个解,输出任意一个即可。

题解

首先,如果 a 中有 0,那么 b 中除了对应的位置为 0,其他位置都为 0。

如果 a 中没有 0,那么 b 中除了对应的位置为 1,其他位置都为 a 中所有元素的乘积。

代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        if (a[i] == 0) cnt++;
    }
    if (cnt > 1) {
        for (int i = 0; i < n; i++) {
            cout << 0 << " ";
        }
        cout << endl;
    } else if (cnt == 1) {
        for (int i = 0; i < n; i++) {
            if (a[i] == 0) {
                cout << accumulate(a.begin(), a.end(), 1LL, multiplies<long long>()) << " ";
            } else {
                cout << 0 << " ";
            }
        }
        cout << endl;
    } else {
        for (int i = 0; i < n; i++) {
            cout << accumulate(a.begin(), a.end(), 1LL, multiplies<long long>()) / a[i] << " ";
        }
        cout << endl;
    }
    return 0;
}

复杂度分析

时间复杂度:O(n)

空间复杂度:O(n)

总结

这道题的题解很简单,但是我在写的时候却出了很多问题,比如说我一开始用的是 int,结果就是 WA,后来改成了 long long,就 AC 了。

CodeForces 1042. D. Subway Pursuit

题目链接

题目

给定一个无向图,每条边都有一个权值,每个点都有一个权值,现在有两个人,他们分别从两个点出发,每次可以走到相邻的点,但是不能走到已经走过的点,问他们能够走到的点的权值和的最大值。

题解

我们可以把这个问题转化为两个人同时从两个点出发,每次可以走到相邻的点,但是不能走到已经走过的点,问他们能够走到的点的权值和的最大值。

我们可以用 dp[i][j]表示第一个人走到 i,第二个人走到 j 时的最大权值和,那么我们可以得到状态转移方程:

dp[i][j] = max(dp[i-1][j] + a[i], dp[i][j-1] + b[j])

代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n + 1), b(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= m; i++) {
        cin >> b[i];
    }
    vector<vector<int>> dp(n + 1, vector<int>(m + 1));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            dp[i][j] = max(dp[i - 1][j] + a[i], dp[i][j - 1] + b[j]);
        }
    }
    cout << dp[n][m] << endl;
    return 0;
}

复杂度分析

时间复杂度:O(nm)

空间复杂度:O(nm)

CodeForces 1042. E. Tree Construction

题目链接

题目

给定一个无向图,每条边都有一个权值,每个点都有一个权值,现在有两个人,他们分别从两个点出发,每次可以走到相邻的点,但是不能走到已经走过的点,问他们能够走到的点的权值和的最大值。

题解

我们可以把这个问题转化为两个人同时从两个点出发,每次可以走到相邻的点,但是不能走到已经走过的点,问他们能够走到的点的权值和的最大值。

我们可以用 dp[i][j]表示第一个人走到 i,第二个人走到 j 时的最大权值和,那么我们可以得到状态转移方程:

dp[i][j] = max(dp[i-1][j] + a[i], dp[i][j-1] + b[j])

代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n + 1), b(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= m; i++) {
        cin >> b[i];
    }
    vector<vector<int>> dp(n + 1, vector<int>(m + 1));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            dp[i][j] = max(dp[i - 1][j] + a[i], dp[i][j - 1] + b[j]);
        }
    }
    cout << dp[n][m] << endl;
    return 0;
}

复杂度分析

时间复杂度:O(nm)

空间复杂度:O(nm)