A. 调饮料师

  • 直接暴力就好了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    signed main() {
    IOS;
    int c[3], s[3];
    for (int i = 0; i < 3; i++) {
    cin >> c[i] >> s[i];
    }
    for (int i = 0; i < 100; i++) {
    int idx = i % 3;
    int tmp = min(c[(idx + 1) % 3] - s[(idx + 1) % 3], s[idx]);
    s[idx] -= tmp;
    s[(idx + 1) % 3] += tmp;
    }
    for (int i = 0; i < 3; i++) {
    cout << s[i] << endl;
    }
    return 0;
    }

B. 心直口筷

  • 差分一下就好了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #define MAX 2000
    int a[MAX];
    int n;
    signed main() {
    IOS;
    cin >> n;
    for (int i = 1; i <= n; i++) {
    int l, r, s;
    cin >> l >> r >> s;
    a[l] += s, a[r + 1] -= s;
    }
    int res = a[0];
    for (int i = 1; i <= 1999; i++) {
    a[i] += a[i - 1];
    res = max(res, a[i]);
    }
    cout << res << endl;

    return 0;
    }

C. 转送苹果

  • 只需要考虑送来的和回来的相不相同就好了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #define MAX 15
    int a[MAX], b[MAX];
    set<int> st;
    signed main() {
    IOS;
    for (int i = 1; i <= 10; i++) {
    cin >> a[i];
    }
    for (int i = 1; i <= 10; i++) {
    cin >> b[i];
    }
    for (int i = 1; i <= 10; i++) {
    for (int j = 1; j <= 10; j++) {
    for (int k = 1; k <= 10; k++) {
    for (int l = 1; l <= 10; l++) {
    if (i == k || j == l) continue;
    st.insert(1000 - a[i] + b[j] - a[k] + b[l]);
    }
    }
    st.insert(1000 - a[i] + b[j]);
    }
    }
    st.insert(1000);
    cout << st.size() << endl;

    return 0;
    }

D. 蜗人赛跑

  • 用单调队列去优化
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #define MAX 1000005
    int a[MAX];
    int x[MAX], s[MAX];
    int L, N, rf, rb;
    deque<int> q;
    signed main()
    {
    IOS;
    cin >> L >> N >> rf >> rb;
    int mx = 0, idx = 0;
    for (int i = 1; i <= N; i++)
    {
    cin >> x[i] >> s[i];
    }
    for (int i = 1; i <= N; i++)
    {
    while (!q.empty() && s[q.back()] < s[i])
    {
    q.pop_back();
    }
    q.push_back(i);
    }
    vector<int> qq;
    qq.push_back(0);
    while (!q.empty())
    {
    qq.push_back(q.front());
    q.pop_front();
    }
    int ans = 0;
    for (int i = 1; i < qq.size(); i++)
    {
    ans += s[qq[i]] * (x[qq[i]] - x[qq[i - 1]]);
    }
    cout << (rf - rb) * ans << endl;

    return 0;
    }

E. 数位清除

  • 发现每个状态不超过5000个, 一共长度100,DP[i][j]表示到i位第j大及以前的数合法的数量
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #define MAX 105
    int n, a, len[MAX], pos[MAX], st[MAX], DP[MAX][5005], ans[MAX][5005];
    const int mod = 1e9 + 7;
    signed main()
    {
    IOS;
    cin >> a >> n;
    for (int i = 1; i <= n + 1; i++) {
    int num = a + i - 1;
    while (num) {
    pos[len[i]++] = num % 10;
    num /= 10;
    }
    int sta = 1 << len[i];
    for (int j = 1; j < sta; j++) {
    st[i]++;
    for (int k = len[i] - 1; k >= 0; k--)
    {
    if (!(j & (1 << k)))
    continue;
    ans[i][st[i]] = ans[i][st[i]] * 10 + pos[k];
    }
    }
    sort(ans[i] + 1, ans[i] + st[i] + 1);
    for (int j = 1; j <= st[i]; j++) {
    int pos = upper_bound(ans[i - 1], ans[i - 1] + st[i - 1] + 1, ans[i][j]) - ans[i - 1] - 1;
    DP[i][j] = (DP[i][j - 1] + DP[i - 1][pos]) % mod;
    if (i == 1)
    DP[i][j] = j;
    }
    }
    cout << DP[n + 1][st[n + 1]] << endl;
    return 0;
    }