P3392 涂国旗

涂国旗

题目描述

某国法律规定,只要一个由 \(N \times M\) 个小方块组成的旗帜符合如下规则,就是合法的国旗。(毛熊:阿嚏——)

  • 从最上方若干行(至少一行)的格子全部是白色的;
  • 接下来若干行(至少一行)的格子全部是蓝色的;
  • 剩下的行(至少一行)全部是红色的;

现有一个棋盘状的布,分成了 \(N\)\(M\) 列的格子,每个格子是白色蓝色红色之一,小 a 希望把这个布改成该国国旗,方法是在一些格子上涂颜料,盖住之前的颜色。

小a很懒,希望涂最少的格子,使这块布成为一个合法的国旗。

输入格式

第一行是两个整数 \(N,M\)

接下来 \(N\) 行是一个矩阵,矩阵的每一个小方块是W(白),B(蓝),R(红)中的一个。

输出格式

一个整数,表示至少需要涂多少块。

样例 #1

样例输入 #1

4 5
WRWRW
BWRWB
WRWRW
RWBWR

样例输出 #1

11

提示

样例解释

目标状态是:

WWWWW
BBBBB
RRRRR
RRRRR

一共需要改 \(11\) 个格子。

数据范围

对于 \(100\%\) 的数据,\(N,M \leq 50\)

2.题解

2.1 循环枚举

思路

由于数据 N,M≤50, 非常之小,所以可以直接先依次枚举出从0->i层所需要修改的格子总数
之后循环枚举,白色格子[1,i],蓝色格子[i+1,j],红色格子[j+1,n], 双重循环即可包含所有情况

代码

#include<bits/stdc++.h>
using namespace std;

int main(){
	int N, M;
	int ans = 2500;
	cin >> N >> M;
	vector<int> white(N+1, 0), blue(N+1, 0), red(N+1, 0);
	for(int i = 1; i <= N; i++){
		string str;
		cin >> str;
		white[i] = white[i-1] + M - count(str.begin(), str.end(), 'W');
		blue[i] = blue[i-1] + M - count(str.begin(), str.end(), 'B');
		red[i] = red[i-1] + M - count(str.begin(), str.end(), 'R');
	}
	
	for(int i = 1; i <= N - 2; i++){
		for(int j = i + 1; j <= N - 1; j++){
			int tmp = 0;
			tmp = white[i] + blue[j] - blue[i] + red[N] - red[j];
			ans = min(ans, tmp);
		}
	}
	cout << ans;
}
posted @ 2024-02-16 22:33  DawnTraveler  阅读(8)  评论(0编辑  收藏  举报