首页 > 试题广场 >

小美的好矩阵

[编程题]小美的好矩阵
  • 热度指数:1939 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
小美定义一个矩阵是好矩阵,当且仅当该矩阵满足:
1. 矩阵仅由'A'、'B'、'C'三种字符组成。且三种字符都出现过。
2. 矩阵相邻的字符都不相等。

现在给定一个n*m的矩阵,小美想知道有多少个3*3的子矩阵是好矩阵,你能帮帮她吗?

输入描述:
第一行输入两个整数n,m,代表矩阵的行数和列数。
接下来的n行,每行输入一个仅包含大写字母的长度为m的字符串。
1\leq n,m \leq 1000


输出描述:
输出一个整数表示答案。
示例1

输入

4 4
DABC
ABAB
BABA
BBAB

输出

1

说明

有4个3*3的子矩阵。
左上角的子矩阵出现了'D',因此不合法。
右上角的是好矩阵。
左下角的存在两个相邻的字母相同,因此不合法。
右下角的子矩阵里没有'C',因此不合法。
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        scanner.nextLine();
        char[][] matrix = new char[n][m];
        for (int i = 0; i < n; i++) {
            matrix[i] = scanner.nextLine().toCharArray();
        }

        int result = 0; // 好矩阵的数量

        // 遍历每个3x3子矩阵
        for (int i = 0; i <= n - 3; i++) {
            for (int j = 0; j <= m - 3; j++) {
                if (isGood(matrix, i, j)) {
                    // 符合条件的使result++
                    result++;
                }
            }
        }
        System.out.println(result);
    }

    // 判断子矩阵是否满足2个条件
    private static boolean isGood(char[][] matrix, int row, int col) {
        Set<Character> set = new HashSet<>();

        for (int x = row; x < row + 3; x++) {
            for (int y = col; y < col + 3; y++) {
                char ch = matrix[x][y];
                set.add(ch);
                // 相邻相等的话,跟右边和跟下面的字符相比较就OK
                if (ch >= 'D' || (y + 1 < col + 3 && ch == matrix[x][y + 1]) || (x + 1 < row + 3 && ch == matrix[x + 1][y])) {
                    return false;
                }
            }
        }
        // 到了这一步表明相邻的字符没有相等的,只剩下判断ABC是否都出现过即可
        return set.size() == 3;
    }
}


发表于 2023-08-18 17:45:42 回复(0)
n,m=[int(i) for i in input().split(' ')]
matrix=[]

for i in range(n):
    matrix.append([j for j in input()])

def judge(matrix, row, col):
    uni_ch=set()
    for x in range(row,row+3):
        for y in range(col,col+3):
            ch=matrix[x][y]
            uni_ch.add(ch)
            if ch >= 'D'&nbs***bsp;(y + 1 < col + 3 and ch == matrix[x][y + 1])&nbs***bsp;(x + 1 < row + 3 and ch == matrix[x + 1][y]):
                return False
    return len(uni_ch)==3
res=0
for i in range(0,n-2):
    for j in range(0,m-2):
        if judge(matrix,i,j):
            res+=1
print(res)
编辑于 2023-10-19 11:23:58 回复(2)
模拟,先去掉含ABC以外的字母和包含相邻且相同的矩阵,再枚举剩下的矩阵字母种类数是否为3
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
using namespace std;

int solve(int n,int m){
    int ans=0;
    string s;
    vector<string> vec;
    while(cin>>s){
        vec.push_back(s);
    }
    unordered_map<char,unordered_set<int>> ump;
    unordered_set<int> ust;
    for(int i=0;i<=n-3;i++){
        for(int j=0;j<=m-3;j++){
            ust.insert(j+i*m);
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            ump[vec[i][j]].insert(j+i*m);
        }
    }
    for(auto& p:ump){
        if(p.first!='A'&&p.first!='B'&&p.first!='C'){
            for(auto q:p.second){
                for(int i=0;i<3;i++){
                    ust.erase(q),ust.erase(q-1),ust.erase(q-2);
                    q-=m;
                }
            }
        }
        else{
            for(auto q:p.second){
                if(p.second.count(q-1)){
                    int r=q;
                    for(int i=0;i<3;i++){
                        ust.erase(r-1),ust.erase(r-2);
                        r-=m;
                    }
                }
                if(p.second.count(q-m)){
                    int r=q;
                    for(int i=0;i<3;i++){
                        ust.erase(r-m),ust.erase(r-2*m);
                        r-=1;
                    }
                }
            }
        }
    }
    for(auto& p:ust){        
        unordered_set<char> tmp;
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                tmp.insert(vec[p/m+i][p%m+j]);
            }
        }
        ans+=(tmp.size()==3);
    }
    return ans;
}

int main() {
    int n,m;
    while(cin>>n>>m){
        cout<<solve(n,m)<<endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")



发表于 2023-08-16 21:56:26 回复(0)
将矩阵化成一个一个的小块,然后根据题目要求进行判断
from collections import Counter

def isGoodMatrix(mtx,idx,idy):
    arr = []
    for i in range(3):
        for j in range(3):
            arr.append(mtx[idx+i][idy+j])
            # 判断条件二 矩阵相邻的字符都不相等。
            if i<2:
                if mtx[idx+i][idy+j] == mtx[idx+i+1][idy+j]:
                    return False
            if j<2:
                if mtx[idx+i][idy+j] == mtx[idx+i][idy+j+1]:
                    return False   
    # 判断条件一 矩阵仅由'A'、'B'、'C'三种字符组成。且三种字符都出现过。        
    temp = set(arr)
    if len(temp)!=3&nbs***bsp;'A' not in temp&nbs***bsp;'B' not in temp&nbs***bsp;'C' not in temp:
        return False    
    return True

def sol(n,m,mat):
    if n<3&nbs***bsp;m<3: return 0
    ans = 0
    for i in range(n-2):
        for j in range(m-2):
            if isGoodMatrix(mat,i,j):
                ans += 1
    return ans

while 1:
    try:
        n,m  = map(int,input().split())
        arr = []
        for i in range(n):
            s = input().strip()
            arr.append([x for x in s])
        ans = sol(n,m,arr)
        print(ans)

    except:
        break


编辑于 2023-10-21 04:12:52 回复(0)
分成三个规矩 限制矩阵:
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        in.nextLine();
        char[][] matrix = new char[n][m];
        boolean[][] polluted = new boolean[n][m];
        for(int i=0;i<n;i++){
            String line = in.nextLine();
            for(int j=0;j<m;j++){
                matrix[i][j] = line.charAt(j);
            }
        }
        
        //遍历一遍设置污染区 含有“ABC”以外的报错
        //往上,往左都g, 范围0-i, 0-j
        //已被污染区跳过
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(polluted[i][j]){
                    continue;
                }
                if(matrix[i][j]!='A' && matrix[i][j]!='B' && matrix[i][j]!='C'){
                    //对区域矩阵进行染***r />                     for(int k = i; k >= Math.max(0, i-2) ; k--){
                        for(int v = j; v>=Math.max(0, j-2); v--){
                            polluted[k][v] = true;
                        }
                    }
                }
            }
        }

        int count = 0;
        //划分每一个小矩阵
        for(int i=0;i< n-2;i++){
            for(int j=0; j < m-2;j++){
                if(polluted[i][j]){
                    continue;
                }
                //对于内部矩阵的每个小块,检查其上下左右
                if(!isCharHasNeighbor(matrix,i,j) &&hasThreeChar(matrix,i,j)) count++;
            }
        }
        System.out.println(count);
    }
    public static boolean hasThreeChar(char[][] matrix, int i, int j){
        int countA = 0;
        int countB = 0;
        int countC = 0;

        for(int k = i;k<= i+2;k++){
            for(int m = j;m <= j+2;m++){
                if(matrix[k][m] == 'A'){
                    countA++;
                }
                if(matrix[k][m] == 'B'){
                    countB++;
                }
                if(matrix[k][m] == 'C'){
                    countC++;
                }
            }
        }
        if(countA>=1 && countB>=1 &&countC>=1 ) return true;
        else return false;
    }
    //i,j为起始坐标,矩阵大小固定为3*3
    public static boolean isCharHasNeighbor(char[][] matrix, int i, int j){
        for(int k = i;k<= i+2;k++){
            for(int m = j;m <= j+2;m++){
                //不在第一行,向上检查
                if((k-i)>0 && matrix[k][m] == matrix[k-1][m]){
                   return true;
                }
                //不在第一列,向左检查
                if((m-j)>0 && matrix[k][m] == matrix[k][m-1]){
                    return true;
                }
                //不在最后一行,向下检查
                if((k-i)<2 && matrix[k][m] == matrix[k+1][m]){
                    return true;
                }
                //不在最后一列,向右检查
                if((m-j)<2 && matrix[k][m] == matrix[k][m+1]){
                    return true;
                }
            }
        }
        return false;
    }
}

发表于 2024-10-11 14:24:06 回复(0)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/11/3 19:34
# @Author  : lanlin
# 小美的好矩阵


def judge33(matrix, y, x):
    result = True

    flag_x = [-1, 0, 1, -1, 0, 1, -1, 0, 1]
    flag_y = [-1, -1, -1, 0, 0, 0, 1, 1, 1]

    flag_ABC = set()
    for i in range(len(flag_y)):

        xx = x+flag_x[i]
        yy = y+flag_y[i]

        temp = matrix[yy][xx]

        # 判断三种字符是否都出现过,且没有其他字符
        if temp in ['A','B','C']:
            flag_ABC.add(temp)
        else:
            return False

        # 判断字符重复,每个元素只需判断其下、右两元素即可
        if (yy+1)<(y+2) and temp == matrix[yy+1][xx]:
            return False
        if (xx+1)<(x+2) and temp == matrix[yy][xx+1]:
            return False

    if len(flag_ABC) != 3:
        result = False

    return result


def judge(data, m, n):
    result = 0
    for y in range(m-2):
        for x in range(n-2):
            if judge33(data, y+1, x+1):
                result += 1
    return result


if __name__=='__main__':
    array1 = input().split(" ")
    m = int(array1[0])
    n = int(array1[1])

    data_array = []

    for i in range(m):
        temp_list = list(input())
        data_array.append(temp_list)

    print(judge(data_array, m, n))

'''
4 4
DABC
ABAB
BABA
BBAB
'''
将矩阵化成一个一个的小块,然后根据题目要求进行判断,注意行列顺序
发表于 2023-11-03 22:01:15 回复(0)
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        // while (in.hasNextInt()) { // 注意 while 处理多个 case
        //     int a = in.nextInt();
        //     int b = in.nextInt();
        //     System.out.println(a + b);
        // }
        int n = in.nextInt();//行
        int m = in.nextInt();//列
        if(n<3||m<3){
            System.out.println(0);
            return;
        }
        char [][]str = new char[n][m];
        for(int i = 0;i<n;i++){
            String input = in.next();
            for(int j = 0;j<m;j++){
                str[i][j] = input.charAt(j);
            }
        }
        int sum = 0;
        for(int i = 0;i<n-2;i++){//控制行的次数
            outer:
            for(int j = 0;j<m-2;j++){//控制列的次数
                String strtemp = "";
                
                for(int x = i;x<i+3;x++){//判断3*3的矩阵是否符合条件
                    for(int y = j;y<j+3;y++){
                        if(str[x][y]!='A'&&str[x][y]!='B'&&str[x][y]!='C'){
                            continue outer;
                        }
                        if(y==j+2&&x!=i+2){
                            if(str[x][y]==str[x+1][y]){
                                continue outer;
                            }
                        }else if(x==i+2&&y!=j+2){
                            if(str[x][y]==str[x][y+1]){
                                continue outer;
                            }
                        }else if(x!=i+2&&y!=j+2){
                            if(str[x][y]==str[x][y+1]||str[x][y]==str[x+1][y]){
                                continue outer;
                            }
                        }
                        strtemp+=str[x][y];
                    }
                }
                if(strtemp.contains("A")&&strtemp.contains("B")&&strtemp.contains("C")){
                    sum+=1;
                }
            }
        }
        System.out.println(sum);
    }
}
发表于 2023-10-09 15:38:01 回复(0)
package main
 
import (
    "fmt"
)
 
func main() {
    var n, m int
    fmt.Scan(&n, &m)
 
    if n < 3 || m < 3 {
        fmt.Println(0)
        return
    }
 
    matrix := make([][]byte, n)
    for i := 0; i < n; i++ {
        var str string
        fmt.Scan(&str)
        strByte := []byte(str)
 
        matrix[i] = make([]byte, m)
        for j := 0; j < m; j++ {
            matrix[i][j] = strByte[j]
        }
    }
 
    good := 0
    for i := 0; i < n-2; i++ {
        for j := 0; j < m-2; j++ {
            // i, j 作为起点
            if isGood(matrix, i, j) {
                good++
            }
        }
    }
 
    fmt.Println(good)
 
}
 
func isGood(matrix [][]byte, row, col int) bool {
    hasA, hasB, hasC := false, false, false
    for i := row; i < row+3; i++ {
        for j := col; j < col+3; j++ {
            ch := matrix[i][j]
            if ch != 'A' && ch != 'B' && ch != 'C' {
                return false
            }
            if ch == 'A' {
                hasA = true
            } else if ch == 'B' {
                hasB = true
            } else if ch == 'C' {
                hasC = true
            } else {
                return false
            }
        }
    }
    if !(hasA && hasB && hasC) {
        return false
    }
 
    for i := row; i < row+2; i++ {
        for j := col; j < col+3; j++ {
            if matrix[i][j] == matrix[i+1][j] {
                return false
            }
        }
    }
 
    for i := row; i < row+3; i++ {
        for j := col; j < col+2; j++ {
            if matrix[i][j] == matrix[i][j+1] {
                return false
            }
        }
    }
 
    return true
}

发表于 2023-08-17 17:13:52 回复(0)