HDU-1838-Chessboard【dp】


1838-Chessboard


        Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)

Problem Description
A chessboard is a NxN binary matrix with rows and columns numbered from 1 to N. Each position of the matrix is black (1) if the sum of the row number and the column number is even; otherwise it is white (0). The following pictures show how a chessboard looks like for N=1, 2 and 3.

Given a NxN binary matrix, find the size of the largest chessboard completely located inside the matrix, as well as the number of chessboards having the largest size (these chessboards may overlap).

Input
The first line of input contains an integer number T, representing the number of test cases to follow. Each test case contains on the first line an integer number N (1<=N<=2000), representing the number of rows and columns of the given matrix. The next N lines describe the matrix: each line contains N characters, which may be either ‘1’ (denoting a black square) or ‘0’ (denoting a white square); at the end of each line there will be a new line character. The matrix will contain at least one ‘1’ character.

Output
For each of the T test cases, in the order given in the input, print one line containing the number of rows and colums of the largest chessboard, followed by a blank and then the number of chessboards having the largest size.

Sample Input
1
5
00101
11010
00101
01010
11101

Sample Output
3 3

题目链接:HDU-1838

题目大意:给出一个棋盘,求形如 这里写图片描述 的最大正方形边长为多少,以及个数。(左上角起点一定为1开始)

题目思路:dp[i][j] 表示 以i,j这个格点为右下角,所能达到的最大边长。

以样例为例:
①首先我们可以确定,如果以绿色部分为右下角,dp[i][j]肯定是1
这里写图片描述

②处理其余部分,如果该格子的值与g[i - 1][j],g[i][j - 1]不相等, 并且与g[i - 1][j - 1]相等 ,即能组成一个正方形。则取三者最小值 + 1

eg:这里写图片描述 紫色部分,满足条件,则取三者最小值,因为只有取最小值+ 1才能组成正方形,否则会有一角不满足条件

③最后统计出最大值有多少个

以下是代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>
#include<iomanip>
using namespace std;
char g[2005][2005];
int dp[2005][2005];  //记录以i,j这个点结尾的所能达到的最大长度 
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        scanf("%d",&n);
        memset(dp,0,sizeof(dp));
        int max_ans = 0;
        getchar();
        for (int i = 0; i < n; i++) scanf("%s",g[i]);
        for (int i = 0; i < n; i++) 
        {
            dp[i][0] = 1;
            dp[0][i] = 1;
        }
        for (int i = 1; i < n; i++)
        {
            for (int j = 1; j < n; j++)
            {
                if (g[i][j] == g[i - 1][j - 1] && g[i][j] != g[i - 1][j] && g[i][j] != g[i][j - 1])
                {
                    dp[i][j] = min(min(dp[i - 1][j - 1],dp[i][j - 1]),dp[i - 1][j]) + 1;
                }
                else dp[i][j] = 1;

                if (g[i][j] == '1')
                {
                    max_ans = max(max_ans,dp[i][j]);
                }
            }
        }
        int ans_cnt = 0;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (max_ans == dp[i][j] && g[i][j] == '1') ans_cnt++;
            }
        }
        printf("%d %d\n",max_ans,ans_cnt);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值