CF1359B New Theatre Square 题解

传送门

补充题目

  • 对于 \(1\times 2\) 的瓷砖,你不可以竖着放(即 \(2\times 1\) 的形式);

  • 有可能全部铺 \(1\times 1\) 的瓷砖会更优。

思路

看到不可以竖着放,我们会很自然地使用贪心。

对于每一行,我们都单独处理。每两个相邻的字符 .,我们都可以使用 \(1\times 2\) 或者是 \(1\times 1\) 的瓷砖来填充,取 \(\min\) 值即可。如果只剩下了一个 .,我们就使用 \(1\times 1\) 的瓷砖。

贪心正确性判断

  • 对于偶数个连续的 .,我们可以全部分成一节节的两个字符的组合,取 \(\min\) 值;

  • 对于奇数个连续的 .,我们可以拆分成偶数个连续的 . 加上一个 .\(1\times 1\))。

因此这个贪心完全正确。

代码

#include <iostream>
#include <cstring>
using namespace std;

int t, n, m, x, y, ans;
string s;

int main() {
    for (cin >> t; t; --t) {
        cin >> n >> m >> x >> y, ans = 0;
        for (int i = 1; i <= n; ++i) {  // 将矩阵分行处理
            cin >> s, s += ' ';  // 尾随空格,防止当i=m-1的时候i+1越界
            for (int i = 0; i < s.size(); ++i) {
                bool o = s[i] == '.' && s[i + 1] == '.'; // 判断是否能铺1*2的瓷砖
                if (o) { // 如果可以
                    s[i] = s[i + 1] = '*' /*不管怎么样,最后都会被铺满*/, 
                    ans += min(2 * x, y); // 只需取1*1和1*2的最小值
                } else if (s[i] == '.') {
                    s[i] = '*', ans += x; // 不行的话就直接铺1*1的瓷砖
                }
            }
        }
        cout << ans << '\n';
    }
    return 0;
}  
posted @ 2023-10-15 14:27  haokee  阅读(20)  评论(0)    收藏  举报