Atcoder Beginner B C 题解

这场出了三个题,虽然没有WA但手速慢了排到300多名,才涨了30几分。。。A题就给两个数a, b,求a + b, a - b, a * b这三者最大值,太简单了,不写了,D题异或和不进位加法乱七八糟的我也不会T^T。。。反正D题我们ACM的一个大佬用尺取写的没过。。。说下B和C吧:

<B>

题意:

给一个串,找一个位置把这个串分割成两部分,问这两部分最多同时具有多少个字母。

思路:

这题直接开一个map <char, bool> flg,就OK啦,枚举所有分割位置,吧第一个串的字母标记,再看第二个串里有多少被标记的字母,再用max维护下即可。

本人AC代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
queue <int> qua;
map <char, bool> flg;

int main() {
    int n;
    char s[105];
    cin >> n;
    scanf("%s", s);
    int maxt = 0;
    for(int i = 0; i < n; i++) {
        flg.clear();
        int cnt = 0;
        for(int j = 0; j <= i; j++) flg[s[j]] = 1;
        for(int k = i + 1; k < n; k++) {
            if(flg[s[k]]) {
                flg[s[k]] = 0;
                cnt++;
            }
        }
        maxt = max(maxt, cnt);
    }
    cout << maxt << endl;

}


<C>

题意:

给一个由W和E组成的串,对于每一个位置,需要让它左边都是E右边都是W,这个位置的值无所谓,问最小改动次数。

思路:

这题稍微有点像CCPC秦皇岛LR串的那个签到题,那题暴力就能过,这题3e5暴力是不存在的了,所以我选择用前缀处理,就是对于每个位置要求左E右W,那我就先从左到右遍历一遍,记一个s1,看有多少个W,就执行s1++, 再把每个位置对应的s1放进sum这个前缀数组里,这样目前每个位置 i 所对应的sum[ i ],就是如果选这个位置,它左边所需要的改动次数,同理,记一个s2, 从右到左遍历一遍,看有多少的E,就执行s2++, 再把每个位置 i 的s2累加到sum[ i ], 用min维护一下即可。

本人AC代码:

#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 7;
queue <int> qua;
map <int, int> mp;
char s[maxn];
int sum[maxn];
int n;

int main() {
    cin >> n;
    scanf("%s", s);
    int mint = maxn - 6;
    int s1 = 0, s2 = 0;
    for(int i = 0; i < n; i++) {
        if(s[i] == 'W') s1++;
        sum[i] = s1;
    }
    for(int i = n - 1; i >= 0; i--) {
        if(s[i] == 'E') s2++;
        sum[i] += s2;
        mint = min(mint, sum[i]);
    }
    cout << mint - 1 << endl;
}

猜你喜欢

转载自blog.csdn.net/ericgipsy/article/details/80470551