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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律