涂条纹
题目描述
只要一个由 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
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。
1.思路解析
因为题目给出的限制,我们可以通过分别枚举涂成白色,蓝色,红色的行数,并进行比较,取出最小值作为答案。
首先定义一个结构体cost
用来储存每一行的每种颜色的个数,如下:
struct cost//定义一个结构体,储存每一行的每种颜色的个数
{
int white,blue,red;
}c[60];//储存每行的花费,全局变量会自动初始化为0
然后在输入的时候预处理。
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>tmp;
//预处理,判断第i行每个格子是什么颜色
if(tmp=='W')
c[i].white++;
if(tmp=='B')
c[i].blue++;
if(tmp=='R')
c[i].red++;
}
最后,循环枚举涂成白色,蓝色,红色的行数,使用一个变量sum
存储当前花费,然后与答案minn
取较小值,更新答案。注意:记得给蓝色和红色分别至少留一行的位置。
2.AC代码
#include<bits/stdc++.h>
using namespace std;
int n,m,minn=2500;//用minn存储答案,不会超过2500
char tmp;//储存当前的颜色
struct cost//定义一个结构体,储存每一行的每种颜色的个数
{
int white,blue,red;
}c[60];//储存每行的花费
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>tmp;
//预处理,判断第i行每个格子是什么颜色
if(tmp=='W')
c[i].white++;
if(tmp=='B')
c[i].blue++;
if(tmp=='R')
c[i].red++;
}
for(int i=1;i<=n-2;i++)//循环涂成白色的行数,总要留两行给蓝色和红色
{
for(int j=1;j<=n-i-1;j++)//循环涂成蓝色的行数,总要留一行给红色
{
int sum=0;
for(int k=1;k<=i;k++)//循环计算涂成白色的花费
sum+=c[k].blue+c[k].red;
for(int k=i+1;k<=i+j;k++)//循环计算涂成蓝色的花费
sum+=c[k].white+c[k].red;
for(int k=i+j+1;k<=n;k++)//循环计算涂成红色的花费
sum+=c[k].white+c[k].blue;
minn=min(minn,sum);//更新答案
}
}
cout<<minn;
return 0;
}
喜欢就订阅此专辑吧!
【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。
欢迎扫码关注蓝胖子编程教育