Codeforces Round #667 (Div. 3).md

A. Yet Another Two Integers Problem

大意:

给出两个数a和b,对于a每次可以加上或者减去1到10里的任意一个数

问多少次操作后可以得到b

思路:

直接算abs(a-b)/10向上取整即可

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int t;
int main() {
    cin >> t;
    while (t--) {
        int a, b, res = 0;
        cin >> a >> b;
        res = abs(a - b) / 10 + ((abs(a-b)%10)!=0);
        cout << res << endl;
    }
    return 0;
}

B. Minimum Product

大意:

给出a,b,x,y,n

现在要求a和b一共减去不大于n的数,且a和b不能小于x和y

(a*b)最小是多少

思路:

要么是先将a减到底,要么是将b减到底

因为a+b的和确定,那么两者的差越大,乘积就越小

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int t;
int main() {
    cin >> t;
    while (t--) {
        LL a, b, x, y, n, res;
        cin >> a >> b >> x >> y >> n;
        LL newa = a, newb = b;
        newa=max(a-n,x);
        if(a-n<x){
            newb = max(b - n+(a - newa), y);
        }
        res = newa * newb;
        newa = a, newb = b;
        newb=max(b-n,y);
        if(b-n<y){
            newa = max(a - n+(b - newb), x);
        }
        cout << min(res,newa*newb) << endl;
    }
    return 0;
}

C. Yet Another Array Restoration

大意:

给出n,x,y

求一个n项等差数列,满足:包含x和y且每一项都为正整数,并且等差数列的最大值最小

思路:

先求y和x的差,然后看这个差最多能被分成多少份,不够的再在x前面以及y的后面添加即可

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int t;
int main() {
    cin >> t;
    while (t--) {
        int n, x, y;
        cin >> n >> x >> y;
        int sub = y - x;
        int l = sub;
        for (int i = 1; i <= sub; i++) {
            if (sub % i == 0) {
                if (1 + sub / i <= n) {
                    l = i;
                    break;
                }
            }
        }
        int rest = n - (1 + sub / l);
        int lrest = ((x-1) / l);
        int rrest = 0;
        if (lrest < rest) {
            rrest += rest - lrest;
        }
        else{
            lrest = rest;
        }
        for (int i = lrest; i >=1; i--) {
            cout << x - i * l << ' ';
        }
        for (int i = 1; i <= (1 + sub / l);i++) {
            cout << x + (i - 1) * l << ' ';
        }
        for (int i = 1; i <= rrest;i++){
            cout << y + i * l << ' ';
        }
        cout << endl;
    }
    return 0;
}

D. Decrease the Sum of Digits

大意:

给出两个数n和s,问把n加多少个1才能使n的数位和小于等于s

思路:

从前到后求n的数位前缀和,如果前缀和不小于s,那么后面都要填0

注意特判,wa哭了...

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int t;
int main() {
    cin >> t;
    while (t--) {
        LL suma = 0, sumb = 0;
        LL n = 0;
        string a, b;
        cin >> a >> b;
        a = "0" + a;
        b = "0" + b;
        for (int i = 1; i < b.size(); i++) {
            sumb = sumb * 10 + b[i] - '0';
        }
        for (int i = 1; i < a.size(); i++) {
            n = 10 * n + a[i] - '0';
            suma += a[i] - '0';
        }
        if (suma <= sumb) {
            cout << "0" << endl;
            continue;
        }
        suma = 0;
        int pos = 0;
        for (int i = 1; i < a.size(); i++) {
            suma += a[i] - '0';
            if (suma < sumb) continue;
            pos = i - 1;
            break;
        }
        a[pos]++;
        LL res = 0;
        for (int i = 0; i <= pos; i++) {
            res = res * 10 + a[i] - '0';
        }
        for (int i = pos + 1; i < a.size(); i++) {
            res = res * 10;
        }
        cout << res - n << endl;
    }
    return 0;
}

E. Two Platforms

大意:

给出n个雨滴的坐标,他们都在往下落,现在给两个长度为k的平板,问最多能接到多少雨滴

思路:

y坐标没有用,所以只需要考虑两个长度为k的区间,最多能包含多少点

贪心的想,这两个区间肯定是不重合最好,所以可以用了l[i]维护这个点左边的长度为k的板子能接的最多的雨滴

r[i]代表这个点右边能接多少,然后枚举i算l[i]+r[i+1]即可

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 5;
typedef long long LL;
int t, a[N];

int l[N], r[N];
int main() {
    cin >> t;
    while (t--) {
        int n, k;
        cin >> n >> k;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
        }
        for (int i = 0; i < n; i++) {
            int x;
            cin >> x;
        }
        l[0] = 0;
        r[n + 1] = 0;
        sort(a + 1, a + n + 1);
        for (int i = 1; i <= n; i++) {
            int pos = lower_bound(a + 1, a + n + 1, a[i] - k) - a;
            int tmp = i - pos + 1;
            l[i] = max(l[i - 1], tmp);
        }
        for (int i = n; i >= 0; i--) {
            int pos = upper_bound(a + 1, a + n + 1, a[i] + k) - a - 1;
            int tmp = pos - i + 1;
            r[i] = max(r[i + 1], tmp);
        }
        int res = 0;
        for (int i = 1; i <= n; i++) {
            res = max(res, l[i] + r[i + 1]);
        }
        cout << res << endl;
    }
    return 0;
}

F. Subsequences of Length Two

大意:

给出两个字符串s和t,其中t的长度为2

现在可以将s中的字符最多修改k次,问修改后s中有多少子序列与t相同

思路:

(dp[i][j][l])代表前i个字符中修改j个字符,且出现(t[0]l)次时的答案

然后根据(a[i])的情况进行更新即可,具体看代码

需要注意的是,如果t0=t1,只需要用公式求出

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int n, k;
LL dp[205][205][205];
string a, b;
int main() {
    cin >> n >> k;
    cin >> a >> b;
    a = " " + a;
    b = " " + b;
    if (b[1] == b[2]) {
        int s = 0;
        for (int i = 1; i <= n; i++) {
            if (a[i] == b[1]) s++;
        }
        s = min(n, s + k);
        cout << s * (s - 1) / 2 << endl;
        return 0;
    }
    memset(dp, 0x8c, sizeof dp);
    LL res = 0;
    for (int i = 0; i <= k; i++) dp[0][i][0] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= k; j++) {
            for (int l = 0; l <= i; l++) {
                dp[i][j][l] = dp[i - 1][j][l];
                if (a[i] == b[1]) {
                    dp[i][j][l] = max(dp[i][j][l], dp[i - 1][j][l - 1]);
                } else if (j) {
                    dp[i][j][l] = max(dp[i][j][l], dp[i - 1][j - 1][l - 1]);
                }
                if (a[i] == b[2]) {
                    dp[i][j][l] = max(dp[i][j][l], dp[i - 1][j][l] + l);
                } else if (j) {
                    dp[i][j][l] = max(dp[i][j][l], dp[i - 1][j - 1][l] + l);
                }
                res = max(res, dp[i][j][l]);
            }
        }
    }
    cout << res << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/14300817.html