首页 > 试题广场 >

小红的矩阵染色

[编程题]小红的矩阵染色
  • 热度指数:5590 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
小红拿到了一个矩阵,初始有一些格子被染成了黑色。现在小红希望把最多k个未被染成黑色的格子染成红色,具体的计分方式是:如果一个红色格子下方相邻的格子也是红色,那么这个红色格子可以获得1分。
小红想知道,最多可以得到多少分?

输入描述:
第一行输入三个正整数n,m,k,代表矩阵的行数和列数、以及小红最多可以染色的格子数量。
接下来的n行,每行输入一个长度为m的字符串,用来表示矩阵的初始染色情况。'*'字符代表黑色,'o'字符代表白色。
1\leq n,m \leq 1000
1\leq k \leq n*m


输出描述:
一个整数,代表小红可以获得的最大分数。
示例1

输入

4 4 3
*o*o
oooo
****
oooo

输出

1

说明

将矩阵染色成如下样式即可('r'代表红色):
*r*o
oroo
****
oooo

示例2

输入

3 3 3
*o*
*o*
*o*

输出

2
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();  // 矩阵行数
        int m = sc.nextInt();  // 矩阵列数
        int k = sc.nextInt();  // 最多可染色的格子数
        char[][] matrix = new char[n][m];
        
        // 读取矩阵数据
        for (int i = 0; i < n; i++) {
            matrix[i] = sc.next().toCharArray();
        }

        List<Integer> blockLengths = new ArrayList<>();
        
        // 按列遍历,找出所有垂直连续的白色块(长度≥2)
        for (int j = 0; j < m; j++) {  // 遍历每一列
            int currentBlockLength = 0;  // 当前连续白色块的长度
            for (int i = 0; i < n; i++) {  // 遍历列中的每一行
                if (matrix[i][j] == 'o') {  // 遇到白色格子,增加块长度
                    currentBlockLength++;
                } else {  // 遇到非白色格子(黑色)
                    // 若当前块长度≥2,记录下来(只有≥2的块才能产生得分)
                    if (currentBlockLength >= 2) {
                        blockLengths.add(currentBlockLength);
                    }
                    currentBlockLength = 0;  // 重置块长度
                }
            }
            // 处理列末尾可能存在的连续白色块
            if (currentBlockLength >= 2) {
                blockLengths.add(currentBlockLength);
            }
        }

        // 按块长度从大到小排序(优先处理长块,能产生更多得分)
        Collections.sort(blockLengths, Collections.reverseOrder());

        int score = 0;
        // 遍历所有块,计算最大得分
        for (int length : blockLengths) {
            if (k == 0) break;  // 染色次数用尽,退出
            
            // 取当前块长度与剩余染色次数的较小值(最多染这么多格子)
            int cellsToDye = Math.min(k, length);
            
            // 只有染色数≥2时才能产生得分(连续2个格子产生1分,3个产生2分,以此类推)
            if (cellsToDye >= 2) {
                score += cellsToDye - 1;
            }
            
            k -= cellsToDye;  // 消耗染色次数
        }

        System.out.println(score);
    }
}

发表于 2025-08-31 11:26:10 回复(0)
这19是怎么出来的嘛,
发表于 2025-11-25 14:38:52 回复(0)
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] first = reader.readLine().split(" ");
        int n = Integer.parseInt(first[0]);
        int m = Integer.parseInt(first[1]);
        int k = Integer.parseInt(first[2]);

        char[][] matrix = new char[n][m];
        for(int i = 0; i < n; i++) {
            matrix[i] = reader.readLine().toCharArray();
        }

        int[] frequence = new int[n+1];

        for(int i = 0; i < m; i++){
            int start = 0;
            while(start < n) {
                if(matrix[start][i] == '*') {
                    start++;
                } else {
                    int end = start + 1;
                    while(end < n && matrix[end][i] == 'o') {
                        end++;
                    }
                    frequence[end-start]++;
                    start = end;
                }
            }
        }
        int max = 0;
        for(int length = n; length > 1 && k > 0; length--){
            for(int i = 0; i < frequence[length]; i++) {
                if (k > length) {
                    max += length - 1;
                    k -= length;
                } else {
                    max += k - 1;
                    k = 0;
                    break;
                }
            }
        }
        System.out.println(max);
    }
}


发表于 2025-10-29 01:11:22 回复(0)
n,m,k = map(int,input().split())
li = []
for i in range(n):
    s = input()
    li.append([j for j in s])
score = []
for row in range(m):
    result = 0
    for col in range(n):
        if li[col][row] == 'o':
            result += 1
        else:
            score.append(result)
            result = 0
    score.append(result)
score.sort()
max_score = 0
while k > 0 and score:
    curr_score = score.pop()
    if curr_score <= 1:
        break
    if k < curr_score:
        max_score += k - 1
        break
    k = k-curr_score
    max_score += curr_score-1
print(max_score)
发表于 2025-10-03 14:50:06 回复(0)
n,m,k = map(int,(input().strip().split()))
#获取矩阵输入
matrix = []
for _ in range(n):
    matrix.append(list(input().strip()))
#生成一个纵向排列的字符串列表
longitude_list = []
for i in range(m):
    a = ''
    for j in range(n):
        a += matrix[j][i]
    longitude_list.append(a)
#所有字符串,按*拆解,不要*,只保留长度大于等于2的字符串,并按长度倒序排序
result_list = []
for i in longitude_list:
    x = i.split('*')
    for j in x:
        if len(j) >= 2:
            result_list.append(j)
result_list.sort(key=len, reverse=True)
#计算当前情况最大的分数
result = 0
already_fill = 0
left_fill = k
i = 0
while left_fill > 0 and i < len(result_list):
    if already_fill + len(result_list[i]) <= k:
        result += len(result_list[i]) -1
        already_fill += len(result_list[i])
        left_fill -= len(result_list[i])
        i +=1
    else:
        result += left_fill -1
        break
print(result)
发表于 2025-10-02 20:03:47 回复(0)
#include <iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n, m, k, score = 0;
    cin >> n >> m >> k;
    vector<string> vec(n);
    for (int i = 0; i < n; i++)
        cin >> vec[i];
    vector<int> white;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (white.empty())
                white.push_back(0);
            if (vec[j][i] == '*') {
                if (white.back() < 2)
                    white.pop_back();
                white.push_back(0);
                continue;
            }
            white.back()++;
        }
        if (!white.empty()&&white.back() < 2)
            white.pop_back();
        white.push_back(0);
    }
    white.pop_back();
    sort(white.begin(), white.end(), [](auto const & a, auto const & b) {
        return a > b;
    });
    for (int num : white) {
        if (num >= k){
            score += k - 1;
            break;
            }
        else {
            k -= num;
            score += num - 1;
        }
    }
    cout << score;
}

发表于 2025-09-18 14:19:08 回复(0)
import sys
a = [ i.replace('\n','') for i in list(sys.stdin)]
n,m,k = tuple(map(int,a[0].split(' ')))
a.pop(0)
max_o = []
score = 0
for j in range(m):
    count = 0
    for i in range(n):
        if a[i][j] == 'o':
            count += 1
        else:
            max_o.append(count)
            count = 0
            continue
    max_o.append(count)
max_o = sorted(max_o,reverse=True)
for j in range(len(max_o)):
    max_geze = max_o[j]
    if k==0&nbs***bsp;max_geze == 0:
        break
    if k > 0:
        if k > max_geze:
            score += max_geze-1
            k -= max_geze
        else:
            score += k-1
            k = 0
print(score)



发表于 2025-08-29 11:08:57 回复(0)
n,m,k = map(int,input().split())
matrix = []
for i in range(n):
    matrix.append(input())

matrix_lie = list(zip(*matrix))
lis_o = []
for i in range(m):
    tmp = ''
    for j in range(n):
        if matrix_lie[i][j]=='o':
            tmp += 'o'
            if j==(n-1) and len(tmp)>=2:
                lis_o.append(tmp)
        else:
            if len(tmp)>=2:
                lis_o.append(tmp)
            tmp = ''
lis_o_sorted = sorted(lis_o,key=lambda x:-len(x))
score = 0
left = k
for item in lis_o_sorted:
    len_item = len(item)
    if left>=len_item:
        score += len_item-1
        left -= len_item
    elif 0<left<len_item:
        score += left-1
        left = 0
    elif left==0:
        break

print(score)
发表于 2025-08-26 01:39:39 回复(0)