洛谷 P3392 涂条纹-普及-
P3392 涂条纹
题目描述
只要一个由 N×MN \times MN×M 个小方块组成的旗帜符合如下规则,就是合法的图案。
- 从最上方若干行(至少一行)的格子全部是白色的;
- 接下来若干行(至少一行)的格子全部是蓝色的;
- 剩下的行(至少一行)全部是红色的;
现有一个棋盘状的布,分成了 NNN 行 MMM 列的格子,每个格子是白色蓝色红色之一,小 a 希望把这个布改成合法图案,方法是在一些格子上涂颜料,盖住之前的颜色。
小 A 很懒,希望涂最少的格子,使这块布成为一个合法的图案。
输入格式
第一行是两个整数 N,MN,MN,M。
接下来 NNN 行是一个矩阵,矩阵的每一个小方块是 W
(白),B
(蓝),R
(红)中的一个。
输出格式
一个整数,表示至少需要涂多少块。
输入输出样例 #1
输入 #1
4 5
WRWRW
BWRWB
WRWRW
RWBWR
输出 #1
11
说明/提示
样例解释
目标状态是:
WWWWW
BBBBB
RRRRR
RRRRR
一共需要改 111111 个格子。
数据范围
对于 100%100\%100% 的数据,N,M≤50N,M \leq 50N,M≤50。
solution
通过枚举三个部分的范围,其实就是两条分割线,找到最小值即可
代码
#include <sstream>
#include "iostream"
#include "cmath"
#include "algorithm"
#include "cstring"
#include "unordered_set"
#include "deque"
#include "stack"
#include "queue"
#include "vector"
#include "unordered_map"using namespace std;const int N = 50;
int R[N], W[N], B[N], n, m;
int TR[N], TW[N], TB[N];int main() {cin >> n >> m;char c;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {cin >> c;if (c == 'R') R[i]++; else if (c == 'B') B[i]++; else W[i]++;}}TR[0] = R[0];TW[0] = W[0];TB[0] = B[0];for (int i = 1; i < n; i++) {TR[i] = TR[i - 1] + R[i];TW[i] = TW[i - 1] + W[i];TB[i] = TB[i - 1] + B[i];}int s = INT32_MAX;for (int i = 0; i < n - 2; i++) {for (int j = i + 1; j < n - 1; j++) {int ss = TR[i] + TB[i] + TR[j] - TR[i] + TW[j] - TW[i] + TB[n - 1] - TB[j] +TW[n-1] - TW[j];if (ss < s)s = ss;}}cout << s;return 0;
}