P3392 涂国旗——暴力枚举

涂国旗

题目描述

某国法律规定,只要一个由 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,M50

分析

c++

  1. 题意很明白,就是分配白蓝红不同的行数,来让涂得格子尽可能少,我们直接暴力枚举每种颜色的所有可能出现行数,然后统计当前状态下需要涂的格子数,然后取最优;
  2. 关于如何枚举,可以发现当白色行数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);
    }
}
"c洛谷国旗"是一个题目,在洛谷在线评测系统上。该题目的要求是给定一个由N×M个小方块组成的棋盘布,每个方块是色、蓝色或红色。你需要按照某国法律规定的国旗规则,将布成合法的国旗。根据法律规定,国旗的布局应该是从最上方若干行(至少一行)的格子全部是色的,接下来若干行(至少一行)的格子全部是蓝色的,剩下的行(至少一行)全部是红色的。你需要通过对格子上颜色的改来实现这个目标。具体来说,你需要在一些格子上上新的颜色来盖住之前的颜色。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [洛谷 P3392 国旗](https://blog.csdn.net/m0_60777643/article/details/122149321)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [洛谷-P3392 国旗](https://blog.csdn.net/weixin_43098069/article/details/107484242)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向上的yyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值