“Shopee杯” 武汉大学(网络预选赛)D - DIY Masks at Home

“Shopee杯” 武汉大学(网络预选赛)D - DIY Masks at Home

题目链接:Click

时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

During the outbreak of COVID-19, xyjj has to stay at home for a long time, which is because he doesn’t have any mask. If he wants to go outside, he must wear a mask to avoid being infected. But if he wants to have a mask, he must go outside to buy one!

Finally, he came up with a solution: Why not DIY at home! Quickly he found the materials required: scissors, needle and threads, and a large piece of cloth (cut from the curtains of his room). To make a mask, he need to cut out a piece of square cloth, and other part of the mask can be easily made so it doesn’t matter. The original cloth can be regarded as a rectangle of n * m cm2, which is made up of 1×1 small colorful squares as the image showing below.

(That’s a typical programmer’s style, isn’t it?)
在这里插入图片描述
However, xyjj doesn’t want his mask to be colorful, so he want the square he selected to have only one single color. Meanwhile, he wants the square to be cut out as large as possible, or the mask might not be able to cover his face. Can you help him with this problem?

输入描述

The input consists of several test cases. The first line contains an integer T, the number of test cases.
For each test case:
The first line will be two integers n, m, which describe the size of the cloth.
For the next n lines, each line will be a string of m upper-case Latin letters, which describe the pattern of the cloth. Each letter refers to a kind of color and places which have the same letters also have the same color
Here it’s guaranteed that .1 ≤ n, m ≤ 2000 and ∑n, ∑m ≤ 2000 for all test cases.

输出描述

For each test case, print one integer ansans in a single line, which is the maximum length of the square we can get. (i.e the result square’s size will be ans*ans cm2).

样例输入#1

1
3 4
AABB
AACC
CCCC

样例输出#1

2

题意

从输入矩阵中,找到最大方形矩阵(同色),输出边长。

分析

别看 n 只有2000,如果暴力的话会变成 2000*2000*2000*2000*k
所以,其实大部分关于最大子矩阵问题,都是dp啦

这题思路还是比较清晰的,关键在于如何寻找状态转移方程,(好吧,dp都这样)

如此定义:dp[i][j] 表示以第 i 行 第 j 列元素为右下角的 子矩阵最大边长
(当然实际上我是从0 0 开始计数的)
状态转移方程:
①若map[i][j] != map[i-1][j-1]
dp[i][j]=1,此时只有一个元素

②若map[i][j] == map[i-1][j-1]
此时计算向上和向左能拓展的最大长度 t
if (t>dp[i-1][j-1]) dp[i][j] = dp[i-1][j-1]+1 拓展一格
否则
dp[i][j]=t; 自立门户
如:
AAAB
AAAB
AAAA
BBAA
对于最后一个元素,t=2,不能拓展,只能自立门户

"Talk is Cheap. Show me the Code."

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 2005;
typedef long long ll;
char map[maxn][maxn];
int dp[maxn][maxn];
int main(void)
{
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, m;
        scanf("%d %d", &n, &m);
        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                scanf(" %c", &map[i][j]);
        for (int i = 0; i < n; i++)//初值
            dp[i][0] = 1;
        for (int j = 0; j < m; j++)
            dp[0][j] = 1;
        int ans = 1;
        for(int i=1;i<n;i++)
            for (int j = 1; j < m; j++) {
                if (map[i][j] != map[i - 1][j - 1]) {
                    dp[i][j] = 1;
                    continue;
                }
                int l = j, u = i, t = 0;
                while (l >= 0 && u >= 0 && map[i][l] == map[i][j] && map[u][j] == map[i][j])
                    l--, u--, t++;//向上,向左拓展
                if (t > dp[i - 1][j - 1])
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                else
                    dp[i][j] = t;
                ans = max(ans, dp[i][j]);
            }
        printf("%d\n", ans);
    }
    return 0;
}

突然发现这题给了5s,很给面子
感谢 sjjda 指出错误

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值