Bootstrap

P3392 涂条纹(C语言)

题目描述

只要一个由 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;
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;