题目描述
某国法律规定,只要一个由 $N \times M$ 个小方块组成的旗帜符合如下规则,就是合法的国旗。从最上方若干行($\geq 1$)的格子全部是白色的
接下来若干行($\geq 1$)的格子全部是蓝色的
剩下的行($\geq 1$)全部是红色的
现有一个棋盘状的破布,分成了 $N$ 行 $M$ 列的格子,每个格子是白色蓝色红色之一,小a希望把这个布改成该国国旗,方法是在一些格子上涂颜料,盖住之前的颜色。
小a很懒,希望涂最少的格子,使这块破布成为一个合法的国旗。
输入格式
第一行是两个整数,$N, M$
接下来 $N$ 行是一个矩阵,矩阵的每一个小方块是W(白),B(蓝),R(红)中的一个
输出格式
一个整数,表示至少需要涂多少块。
输入样例4 5
WRWRW
BWRWB
WRWRW
RWBWR
输出样例11
说明/提示
目标状态是WWWWW
BBBBB
RRRRR
RRRRR
一共需要改 $11$ 个格子
对于 $100%$ 的数据,$N, M \leq 50$
思路
可以看出这面旗帜必有三种颜色,且从上往下依次出现的颜色一定是W, B, R,故可以暴力枚举所有可分割的情况,三种颜色只需分割两次,用一个嵌套循环解决!
AC代码#include
#include
using namespace std;
int n, m;
char g[50][50];
int ans = 0x3f3f3f3f;
int fillMap(int s, int x)
{
int res = 0;
for (int i = 0; i < s; i ++)
for (int j = 0; j < m; j ++)
if (g[i][j] != 'W')
res ++;
for (int i = s; i < x; i ++)
for (int j = 0; j < m; j ++)
if (g[i][j] != 'B')
res ++;
for (int i = x; i < n; i ++)
for (int j = 0; j < m; j ++)
if (g[i][j] != 'R')
res ++;
return res;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> g[i][j];
for (int i = 1; i < n; i ++)
for (int j = i + 1; j < n; j ++)
ans = min(ans, fillMap(i, j));
cout << ans << endl;
return 0;
}