题目描述
只要一个由 N×M 个小方块组成的旗帜符合如下规则,就是合法的图案。
- 从最上方若干行(至少一行)的格子全部是白色的;
- 接下来若干行(至少一行)的格子全部是蓝色的;
- 剩下的行(至少一行)全部是红色的;
现有一个棋盘状的布,分成了 N 行 M 列的格子,每个格子是白色蓝色红色之一,小 a 希望把这个布改成合法图案,方法是在一些格子上涂颜料,盖住之前的颜色。
小 A 很懒,希望涂最少的格子,使这块布成为一个合法的图案。
输入格式
第一行是两个整数 N,M。
接下来 NN 行是一个矩阵,矩阵的每一个小方块是 W
(白),B
(蓝),R
(红)中的一个。
输出格式
一个整数,表示至少需要涂多少块。
输入输出样例
输入 #1复制
4 5 WRWRW BWRWB WRWRW RWBWR
输出 #1复制
11
说明/提示
样例解释
目标状态是:
WWWWW
BBBBB
RRRRR
RRRRR
一共需要改 1111 个格子。
数据范围
对于 100% 的数据,N,M≤50。
分析
这道题就是将N*M个小方块以行为分解分成白,蓝,红三个色块,数据最大只有50,那我们可以考虑直接暴力枚举,枚举的变量就是每两个色块的分界的行位置。
#include<stdio.h>
int n,m;
char s[51][51]={'\0'};
//count函数用来计i行到j行中需要涂色的方块数,t为目标颜色。
int count(int i,int j,char t)
{
int ans=0;
while(i<=j)
{
for(int k=0;k<n;k++)
{
if(s[i][k]!=t)ans++;
}
i++;
}
return ans;
}
int main()
{
//最大只有2500个格子。
int ans=2500;
scanf("%d%d",&m,&n);
for(int i=0;i<m;i++)
scanf("%s",s[i]);
//外层的for循环是循环白蓝分界,因为每个颜色都要有那么最后至少留出两行。
for(int i=0;i<m-2;i++)
{
int min;
//内存for循环是循环蓝红分界,这里我是倒着枚举从倒数第二行开始。
for(int j=m-2;j>i;j--)
{
//这就是简单的计数和替换。
min=count(0,i,'W')+count(i+1,j,'B')+count(j+1,m-1,'R');
if(min<ans)ans=min;
}
}
printf("%d",ans);
return 0;
}