Codeforces Round #681 (Div. 2) 补题 B. Saving the City 贪心

思维+贪心B. Saving the City

解题思路

如果只有 1 1 1 个连续 1 1 1 的区域,输出 a a a。否则从第二个连续1的区域开始贪心地考虑:是直接引爆自己 ( a ) (a) (a),还是把左边和自己中间填满之后引爆 ( n × b ) (n × b) (n×b)

注意事项

1.虽然题目中说输入是 a string consisting of zeros and ones,但是是有可能输入全 0 0 0 的数据的。所以最后输出的时候要判断有没有 1 1 1

2.如果是从第二个连续 1 1 1 的地方开始判断,要记得多加一个 a a a

参考代码

#include<bits/stdc++.h>
using namespace std;
#define LOCAL  //提交的时候一定注释
#define _for(i, a, b) for(int i = (a); i < (b); ++i)
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define pb push_back
#define VI vector<int>
#define maxn 100010
#define INF 0x3f3f3f3f
typedef long long LL;
typedef double db;
const double eps = 1e-6;  //定义浮点数误差
const int MOD = 998244353;

int readint(){
    
    
    int x; scanf("%d", &x); return x;
}

int main() {
    
    
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int t, n, a, b;
    char str[maxn];
    scanf("%d", &t);
    while (t--) {
    
    
        a = readint(); b = readint();
        scanf("%s", str);
        int one = 0, cnt = 0, res = 0;
        bool find = false;
        _for(i, 0, strlen(str)) {
    
    
            //one |= str[i];
            if (str[i] == '1') find = true;
            if (str[i] == '0') {
    
    
                if (find) cnt++;  //如果之前出现过1了,说明接下来至少是第二个连续1的区域,需要判断
            } else if (cnt > 0) {
    
      //当前为1的时候,若左边有0,判断是否要连起来
                res += (cnt * b < a) ? cnt * b : a;
                cnt = 0;  //重新开始计数
            }
        }
        printf("%d\n", find ? res + a : res);  //没出现过的话不用加上a
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Encore47/article/details/109492243