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\)。
2.题解
2.1 循环枚举
思路
由于数据 N,M≤50, 非常之小,所以可以直接先依次枚举出从0->i层所需要修改的格子总数
之后循环枚举,白色格子[1,i],蓝色格子[i+1,j],红色格子[j+1,n], 双重循环即可包含所有情况
代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int N, M;
int ans = 2500;
cin >> N >> M;
vector<int> white(N+1, 0), blue(N+1, 0), red(N+1, 0);
for(int i = 1; i <= N; i++){
string str;
cin >> str;
white[i] = white[i-1] + M - count(str.begin(), str.end(), 'W');
blue[i] = blue[i-1] + M - count(str.begin(), str.end(), 'B');
red[i] = red[i-1] + M - count(str.begin(), str.end(), 'R');
}
for(int i = 1; i <= N - 2; i++){
for(int j = i + 1; j <= N - 1; j++){
int tmp = 0;
tmp = white[i] + blue[j] - blue[i] + red[N] - red[j];
ans = min(ans, tmp);
}
}
cout << ans;
}