题目大意
题目真的是不说人话......
有一个国家的国旗是由一个 N * M 的方格组成的。如果想要这面国旗合法,就必须满足要求:
- 国旗从上到下必须是白色、蓝色和红色,顺序不能改变。
- 每一种颜色都至少有一行。
小a这时候捡到了一块破布,希望你通过涂颜色的方式,把破布成合法的国旗,并且要求涂的地方最少,输出有几个要涂的地方。
话说这小a......
然后这国旗好像是俄罗斯的
思路
一开始我还在想dp,想不出来,一看数据范围......
连100都不到,dp啥啊......吐槽一句,这要不是kkk出的题,肯定是红的。还橙题唉
废话说完了。思路就是暴力。但是我们需要先做一下初始化。初始化什么呢?
大家想一想,我们是要统计最少的填涂次数。所以,我们把每一行不是 "W"、"B"、"R"的代价算出来,存到三个数组里。
好,现在有了这些东西,开始正式暴力了。
我们其实只需要枚举两条分割线,分割线就是两种不同颜色中间的那条线。这样,有了两条分割线,就可以算答案,然后取最小值就行了。
ok啊,看代码!
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#define MAXN 55
using namespace std;
int n, m;
char s[MAXN][MAXN];
int cntW[MAXN], cntB[MAXN], cntR[MAXN];
int answer = 1e9;
int main () {
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
int cnt1 = 0, cnt2 = 0, cnt3 = 0;
for (int j = 1; j <= m; ++j) {
cin >> s[i][j];
if (s[i][j] != 'W') cnt1 += 1;
if (s[i][j] != 'B') cnt2 += 1;
if (s[i][j] != 'R') cnt3 += 1;
cntW[i] = cnt1;
cntB[i] = cnt2;
cntR[i] = cnt3;
}
}
int c = 0;
for (int i = 2; i <= n - 1; ++i) {
for (int j = i; j <= n - 1; ++j) {
for (int a = 1; a < i; ++a) {
c += cntW[a];
}
for (int a = i; a <= j; ++a) {
c += cntB[a];
}
for (int a = j + 1; a <= n; ++a) {
c += cntR[a];
}
answer = min (answer, c);
c = 0;
}
}
cout << answer << endl;
return 0;
}
完结散花。
道路千万条,自己编码第一条。
复制棕名后,陶片放逐两行泪。