P3392 涂条纹——暴力枚举典型题目

题目描述

只要一个由 \(N \times M\) 个小方块组成的旗帜符合如下规则,就是合法的图案。

  • 从最上方若干行(至少一行)的格子全部是白色的;
  • 接下来若干行(至少一行)的格子全部是蓝色的;
  • 剩下的行(至少一行)全部是红色的;

现有一个棋盘状的布,分成了 \(N\)\(M\) 列的格子,每个格子是白色蓝色红色之一,小 a 希望把这个布改成合法图案,方法是在一些格子上涂颜料,盖住之前的颜色。

小 A 很懒,希望涂最少的格子,使这块布成为一个合法的图案。

输入格式

第一行是两个整数 \(N,M\)

接下来 \(N\) 行是一个矩阵,矩阵的每一个小方块是 W(白),B(蓝),R(红)中的一个。

输出格式

一个整数,表示至少需要涂多少块。

输入输出样例 #1

输入 #1

4 5
WRWRW
BWRWB
WRWRW
RWBWR

输出 #1

11

说明/提示

样例解释

目标状态是:

WWWWW
BBBBB
RRRRR
RRRRR

一共需要改 \(11\) 个格子。

数据范围

对于 \(100\%\) 的数据,\(N,M \leq 50\)

题解

#include <iostream>
#include <vector>
#include <climits>
using namespace std;
// 计算某一行需要涂成指定颜色的格子数
int countToPaint(const vector<string>& flag, int row, char color) {
int count = 0;
for (char c : flag[row]) {
if (c != color) {
count++;
}
}
return count;
}
int main() {
int N, M;
cin >> N >> M;
vector<string> flag(N);
for (int i = 0; i < N; ++i) {
cin >> flag[i];
}
int minPaints = INT_MAX;
// 枚举白色区域的行数,至少 1 行
for (int i = 1; i <= N - 2; ++i) {
// 枚举蓝色区域的行数,至少 1 行
for (int j = 1; j <= N - i - 1; ++j) {
int paints = 0;
// 计算白色区域需要涂色的格子数
for (int k = 0; k < i; ++k) {
paints += countToPaint(flag, k, 'W');
}
// 计算蓝色区域需要涂色的格子数
for (int k = i; k < i + j; ++k) {
paints += countToPaint(flag, k, 'B');
}
// 计算红色区域需要涂色的格子数
for (int k = i + j; k < N; ++k) {
paints += countToPaint(flag, k, 'R');
}
// 更新最小涂色格子数
minPaints = min(minPaints, paints);
}
}
cout << minPaints << endl;
return 0;
}
发布于   xiins  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示