HDU 2870 Largest Submatrix (最大子矩阵)

Largest Submatrix

Time Limit: 2000/1000 MS (Java/Others)   

Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 860    Accepted Submission(s): 421

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

 

View Code
  1 /*
  2   跟1505类似,只不过要加上枚举,比较麻烦一点而已。
  3   首先将可变成a的全部变成a,记录每一层中a左右可达的边界,然后从上到下找出第i层往上能达到的最大矩阵
  4   然后同样把可变成b的全部变成b,做同样的步骤,最后再枚举c。求出最大值即使答案。
  5 
  6   375MS    13160K
  7 
  8 #include <iostream>
  9 #include <cstdio>
 10 #include <cstring>
 11 #include <string>
 12 #include <algorithm>
 13 #define SIZE 1005
 14 
 15 using namespace std;
 16 
 17 int lt[SIZE][SIZE],rt[SIZE][SIZE];
 18 int height[SIZE][SIZE];
 19 int n,m;
 20 int ans;
 21 string s[SIZE];
 22 
 23 void cal()
 24 {
 25     for(int i=1; i<=n; i++)
 26         for(int j=1; j<=m; j++)
 27             lt[i][j] = rt[i][j] = j;
 28     for(int i=1; i<=n; i++)
 29         height[i][0] = height[i][m+1] = -1;
 30     for(int i=1; i<=n; i++)
 31     {
 32         for(int j=1; j<=m; j++)
 33         {
 34             while(height[i][lt[i][j]-1] >= height[i][j])
 35                 lt[i][j] = lt[i][lt[i][j]-1];
 36         }
 37     }
 38     for(int i=1; i<=n; i++)
 39     {
 40         for(int j=m; j>=1; j--)
 41         {
 42             while(height[i][rt[i][j]+1] >= height[i][j])
 43                 rt[i][j] = rt[i][rt[i][j]+1];
 44         }
 45     }
 46     for(int i=1; i<=n; i++)
 47         for(int j=1; j<=m; j++)
 48             ans = max(ans,(rt[i][j]-lt[i][j]+1)*height[i][j]);
 49 }
 50 
 51 int main()
 52 {
 53     while(~scanf("%d%d",&n,&m))
 54     {
 55         for(int i=1; i<=n; i++)
 56             s[i].clear();
 57         string temp;
 58         for(int i=1; i<=n; i++)
 59         {
 60             cin >> temp;
 61             s[i] += '0';
 62             s[i] += temp;
 63         }
 64         ans = 0;
 65         for(int i=0; i<=m; i++)
 66             height[0][i] = 0;
 67         for(int i=1; i<=n; i++)
 68         {
 69             for(int j=1; j<=m; j++)
 70             {
 71                 if(s[i][j] == 'a' || s[i][j] == 'w' || s[i][j] == 'y' || s[i][j] == 'z')
 72                     height[i][j] = height[i-1][j]+1;
 73                 else
 74                     height[i][j] = 0;
 75             }
 76         }
 77         cal();
 78         for(int i=1; i<=n; i++)
 79         {
 80             for(int j=1; j<=m; j++)
 81             {
 82                 if(s[i][j] == 'b' || s[i][j] == 'w' || s[i][j] == 'x' || s[i][j] == 'z')
 83                      height[i][j] = height[i-1][j]+1;
 84                 else
 85                     height[i][j] = 0;
 86             }
 87         }
 88         cal();
 89         for(int i=1; i<=n; i++)
 90         {
 91             for(int j=1; j<=m; j++)
 92             {
 93                 if(s[i][j] == 'c' || s[i][j] == 'y' || s[i][j] == 'x' || s[i][j] == 'z')
 94                      height[i][j] = height[i-1][j]+1;
 95                 else
 96                     height[i][j] = 0;
 97             }
 98         }
 99         cal();
100         printf("%d\n",ans);
101     }
102     return 0;
103 }
104 */
105 
106 /*
107   可将lt[][],rt[][]降维成lt[],rt[],循环每一层的时候顺便求出最大值,节省了一半空间消耗
108   343MS    5272K
109   */
110 #include <iostream>
111 #include <cstdio>
112 #include <cstring>
113 #include <string>
114 #include <algorithm>
115 #define SIZE 1005
116 
117 using namespace std;
118 
119 int lt[SIZE],rt[SIZE];
120 int height[SIZE][SIZE];
121 int n,m;
122 int ans;
123 string s[SIZE];
124 
125 void cal()
126 {
127     for(int i=1; i<=n; i++)
128     {
129         for(int j=1; j<=m; j++)
130             lt[j] = rt[j] = j;
131         height[i][0] = height[i][m+1] = -1;
132         for(int j=1; j<=m; j++)
133         {
134             while(height[i][lt[j]-1] >= height[i][j])
135                 lt[j] = lt[lt[j]-1];
136         }
137         for(int j=m; j>=1; j--)
138         {
139             while(height[i][rt[j]+1] >= height[i][j])
140                 rt[j] = rt[rt[j]+1];
141         }
142         for(int j=1; j<=m; j++)
143             ans = max(ans,(rt[j]-lt[j]+1)*height[i][j]);
144     }
145 }
146 
147 int main()
148 {
149     while(~scanf("%d%d",&n,&m))
150     {
151         for(int i=1; i<=n; i++)
152             s[i].clear();
153         string temp;
154         for(int i=1; i<=n; i++)
155         {
156             cin >> temp;
157             s[i] += '0';
158             s[i] += temp;
159         }
160         ans = 0;
161         for(int i=0; i<=m; i++)
162             height[0][i] = 0;
163         for(int i=1; i<=n; i++)
164         {
165             for(int j=1; j<=m; j++)
166             {
167                 if(s[i][j] == 'a' || s[i][j] == 'w' || s[i][j] == 'y' || s[i][j] == 'z')
168                     height[i][j] = height[i-1][j]+1;
169                 else
170                     height[i][j] = 0;
171             }
172         }
173         cal();
174         for(int i=1; i<=n; i++)
175         {
176             for(int j=1; j<=m; j++)
177             {
178                 if(s[i][j] == 'b' || s[i][j] == 'w' || s[i][j] == 'x' || s[i][j] == 'z')
179                      height[i][j] = height[i-1][j]+1;
180                 else
181                     height[i][j] = 0;
182             }
183         }
184         cal();
185         for(int i=1; i<=n; i++)
186         {
187             for(int j=1; j<=m; j++)
188             {
189                 if(s[i][j] == 'c' || s[i][j] == 'y' || s[i][j] == 'x' || s[i][j] == 'z')
190                      height[i][j] = height[i-1][j]+1;
191                 else
192                     height[i][j] = 0;
193             }
194         }
195         cal();
196         printf("%d\n",ans);
197     }
198     return 0;
199 }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值