涂国旗
题目描述
某国法律规定,只要一个由 N × M N \times M N×M 个小方块组成的旗帜符合如下规则,就是合法的国旗。(毛熊:阿嚏——)
- 从最上方若干行(至少一行)的格子全部是白色的;
- 接下来若干行(至少一行)的格子全部是蓝色的;
- 剩下的行(至少一行)全部是红色的;
现有一个棋盘状的布,分成了 N N N 行 M M M 列的格子,每个格子是白色蓝色红色之一,小 a 希望把这个布改成该国国旗,方法是在一些格子上涂颜料,盖住之前的颜色。
小a很懒,希望涂最少的格子,使这块布成为一个合法的国旗。
输入格式
第一行是两个整数 N , M N,M N,M。
接下来
N
N
N 行是一个矩阵,矩阵的每一个小方块是W
(白),B
(蓝),R
(红)中的一个。
输出格式
一个整数,表示至少需要涂多少块。
样例 #1
样例输入 #1
4 5
WRWRW
BWRWB
WRWRW
RWBWR
样例输出 #1
11
提示
样例解释
目标状态是:
WWWWW
BBBBB
RRRRR
RRRRR
一共需要改 11 11 11 个格子。
数据范围
对于 100 % 100\% 100% 的数据, N , M ≤ 50 N,M \leq 50 N,M≤50。
分析
c++
- 题意很明白,就是分配白蓝红不同的行数,来让涂得格子尽可能少,我们直接暴力枚举每种颜色的所有可能出现行数,然后统计当前状态下需要涂的格子数,然后取最优;
- 关于如何枚举,可以发现当白色行数w只能是1到n-2,蓝色在白色基础上是w+1到n-1,当白蓝已定,总行数已知,红的行数就知道了,然后统计每种情况要涂的格子即可;
#include<bits/stdc++.h>
using namespace std;
int n, m, ans = 10000;
char a[55][55];
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
//枚举红色行数
for (int w = 1; w <= n - 2; w++) {
//蓝色行数
for (int b = w + 1; b <= n - 1; b++) {
int cnt = 0;
//涂1到w行
for (int i = 1; i <= w; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] != 'W')
cnt++;
}
}
//涂w+1行到b行
for (int i = w + 1; i <= b; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] != 'B')
cnt++;
}
}
//涂b+1行到n行
for (int i = b + 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] != 'R')
cnt++;
}
}
ans = min(ans, cnt);
}
}
cout << ans;
return 0;
}
java
import java.util.Scanner;
public class Main {
static char[][] c = new char[55][55];
//将输入存在字符数组c中
static void change(int i, String s) {
char[] ch = s.toCharArray();
for (int j = 0; j < ch.length; j++) {
c[i+1][j+1] = ch[j];
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int ans=Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
String s = sc.next();
change(i, s);//转化为字符数组
}
for(int i=1;i<=n-2;i++){//涂白的最底线(最下边到达的边界)
for(int j=i+1;j<=n-1;j++){//涂蓝的最底线
int cnt=0;//记录每一种方案的需要涂格子数
//涂白
for(int k=1;k<=i;k++){
for(int l=1;l<=m;l++){
if(c[k][l]!='W')
cnt++;
}
}
//涂蓝
for(int k=i+1;k<=j;k++){//k从i+1
for(int l=1;l<=m;l++){
if(c[k][l]!='B')
cnt++;
}
}
//涂红
for(int k=j+1;k<=n;k++){//k从j+1
for(int l=1;l<=m;l++){
if(c[k][l]!='R')
cnt++;
}
}
ans=Math.min(ans,cnt);
}
}
System.out.println(ans);
}
}