某十八线不知名小型编程比赛初赛的两道编程题题解

如果我的代码是错的就踢我一脚

T26. D 什么 P

题面

\(n\) 个超市,在第 \(i\) 个超市中,你可以用 \(a_i\) 的价格买入一件价值为 \(b_i\) 的商品,或用 \(c_i\) 的价格买入一件价值为 \(d_i\) 的商品,或者不买。

请在花费不超过 \(m\) 的前提下最大化买入商品的价值与提前给定的整数 \(s\) 的和。

保证所有输入的整数不超过 \(10^4\)\(n\le 2\times 10^2\)

思路

加了点料的01背包模板。

定义 \(d_{i,j,k}(j\in \set{0,1,2})\) 为路过第 \(i\) 个超市,购买了第 \(j\) 种商品(\(j=0\) 表示不买)时花费 \(k\) 所得商品的最大价值。

转移时只需考虑 \(\max(d_{i,0,k},d_{i,1,k},d_{i,2,k})\) 即可。

时间复杂度 \(O(nm)\)

代码

#include <iostream>
#include <cstring>
using namespace std;
const int N = 2e2 + 10, M = 1e4 + 10;
int m, n, s, dp[2][3][M], res;
const int sz = sizeof dp;
int main()
{
    scanf("%d%d%d", &m, &n, &s);
    for (int i = 1, a, b, c, d, t = 1; t <= n; t++, i = !i)
    {
        scanf("%d%d%d%d", &a, &b, &c, &d);
        for (int j = 0; j <= m; j++)
        {
            dp[i][0][j] = max(dp[i ^ 1][0][j], max(dp[i ^ 1][1][j], dp[i ^ 1][2][j]));
        }
        memcpy(dp[i][1], dp[i][0], (m + 1) << 2);
        memcpy(dp[i][2], dp[i][0], (m + 1) << 2);
        for (int j = m; j >= b; j--)
        {
            dp[i][1][j] = max(dp[i][1][j], dp[i][1][j - b] + a);
        }
        for (int j = m; j >= d; j--)
        {
            dp[i][2][j] = max(dp[i][2][j], dp[i][2][j - d] + c);
        }
    }
    for (int j = 0; j <= m; j++)
    {
        dp[n & 1 ^ 1][0][j] = max(dp[n & 1][0][j], max(dp[n & 1][1][j], dp[n & 1][2][j]));
    }
    for (int j = 0; j <= m; j++)
    {
        res = max(res, dp[n & 1 ^ 1][0][j]);
    }
    printf("%d\n", res + s);
}

T27. 历史记录

题面

你有一个正在访问网址 https://www.ZhongGuoXin.com 的浏览器。

你需要支持 \(n\) 次浏览器历史记录的回溯/撤销/访问操作,并在每次操作后输出目前浏览器正在访问的网址,并进行错误捕获。

\(n\le 100\)

思路

模拟即可。

使用 vector 容器模拟访问栈(因为 stack 不支持容器内元素访问)。

时间复杂度 \(O(n)\)

代码

#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> vs;
int n, piv;
string op, wb;
int main()
{
    cin >> n;
    vs.push_back("https://www.ZhongGuoXin.com");
    for (int i = 1; i <= n; i++)
    {
        cin >> op;
        if (op == "Exit")
            continue;
        if (op == "Go")
        {
            cin >> wb;
            vs.resize(piv + 2);
            vs.back() = wb;
            cout << wb << '\n';
            piv++;
            continue;
        }
        if (op == "Next")
        {
            if (piv + 1 == vs.size())
            {
                puts("Error");
                continue;
            }
            piv++;
            cout << vs[piv] << '\n';
            continue;
        }
        if (!piv)
        {
            puts("Error");
            continue;
        }
        piv--;
        cout << vs[piv] << '\n';
    }
}
posted @ 2024-06-16 17:32  丝羽绫华  阅读(4)  评论(0编辑  收藏  举报