1. 程式人生 > >HDU2870_Largest Submatrix【最大完全子矩陣】

HDU2870_Largest Submatrix【最大完全子矩陣】

Largest Submatrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1589    Accepted Submission(s): 761
Problem Description
Now here is a matrix with letter 'a','b','c','w','x','y','z' and you can change 'w' to 'a' or 'b', change 'x' to 'b' or 

'c', change 'y' to 'a' or 'c', and change 'z' to 'a', 'b' or 'c'. After you changed it, what's the largest submatrix with 

the same letters you can make?
 
Input
The input contains multiple test cases. Each test case begins with m and n (1 ≤ m, n ≤ 1000) on line. Then come the 

elements of a matrix in row-major order on m lines each with n letters. The input ends once EOF is met.
 
Output
For each test case, output one line containing the number of elements of the largest submatrix of all same letters.
 
Sample Input
2 4
abcw
wxyz
 
Sample Output
3
 
Source

2009 Multi-University Training Contest 7 - Host by FZU

題目大意:有個字母矩陣,包含字母"a、b、c、w、x、y、z",其中,w能變為"a、b",

x能變為"b、c",y能變為"a、c",z能變為"a、b、c"。問能構成的最大字母完全一樣的子

矩陣面積為多大?

思路:和HDU1505、HDU1506一樣的思路,其中a[i][j]表示轉換為字母a後以第i行為底,

第j列上方連續空閒位置的高度。b[i][j]表示字母b……,c[i][j]表示字母c……

遍歷計算出該點向左右兩邊延伸的左右邊界,從而計算出面積,最終比較計算出最大面積。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

int a[1100][1100],b[1100][1100],c[1100][1100],l[1100],r[1100];

int main()
{
    int M,N;
    char ch;
    while(~scanf("%d%d",&M,&N))
    {
        for(int i = 1; i <= M; i++)
        {
            getchar();
            for(int j = 1; j <= N; j++)
            {
                scanf("%c",&ch);
                if(ch=='a' || ch=='w' || ch=='y' || ch=='z')
                    a[i][j] = a[i-1][j] + 1;
                else
                    a[i][j] = 0;
                if(ch=='b' || ch=='w' || ch=='x' || ch=='z')
                    b[i][j] = b[i-1][j] + 1;
                else
                    b[i][j] = 0;
                if(ch=='c' || ch=='x' || ch=='y' || ch=='z')
                    c[i][j] = c[i-1][j] + 1;
                else
                    c[i][j] = 0;
            }
        }

        int area = -0xffffff0;
        for(int i = 1; i <= M; i++)
        {
//            ------------------求a最大面積---------------
            l[0] = 1,r[N+1] = N;
            a[i][0] = a[i][N+1] = -1;
            for(int j = 1; j <= N; j++)
            {
                l[j] = j;
                while(a[i][l[j]-1] >= a[i][j])
                    l[j] = l[l[j]-1];
            }
            for(int j = N; j >= 1; j--)
            {
                r[j] = j;
                while(a[i][r[j]+1] >= a[i][j])
                    r[j] = r[r[j]+1];
            }
            for(int j = 1; j <= N; j++)
            {
                if(a[i][j] * (r[j]-l[j]+1) > area)
                    area = a[i][j] * (r[j]-l[j]+1);
            }
//            ----------------求b最大面積----------------
            l[0] = 1,r[N+1] = N;
            b[i][0] = b[i][N+1] = -1;
            for(int j = 1; j <= N; j++)
            {
                l[j] = j;
                while(b[i][l[j]-1] >= b[i][j])
                    l[j] = l[l[j]-1];
            }
            for(int j = N; j >= 1; j--)
            {
                r[j] = j;
                while(b[i][r[j]+1] >= b[i][j])
                    r[j] = r[r[j]+1];
            }
            for(int j = 1; j <= N; j++)
            {
                if(b[i][j] * (r[j]-l[j]+1) > area)
                    area = b[i][j] * (r[j]-l[j]+1);
            }
//            -------------求c最大面積---------------
            l[0] = 1,r[N+1] = N;
            c[i][0] = c[i][N+1] = -1;
            for(int j = 1; j <= N; j++)
            {
                l[j] = j;
                while(c[i][l[j]-1] >= c[i][j])
                    l[j] = l[l[j]-1];
            }
            for(int j = N; j >= 1; j--)
            {
                r[j] = j;
                while(c[i][r[j]+1] >= c[i][j])
                    r[j] = r[r[j]+1];
            }
            for(int j = 1; j <= N; j++)
            {
                if(c[i][j] * (r[j]-l[j]+1) > area)
                    area = c[i][j] * (r[j]-l[j]+1);
            }
        }
        printf("%d\n",area);
    }
    return 0;
}