2020武大校赛预赛D题

悬线法需要维护三个数组,L[n][m],R[n][m],H[n][m]。

以 Luogu P1169 棋盘制作为例。

 (图源自洛谷https://www.luogu.com.cn/blog/RPdreamer/#,侵删)

如果把 L[n][m] 和 H[n][m] 放在一起维护,例如

 

 上图蓝色部分的 L[i][j-1] 已经变为 min(L[i][j-1], L[i-1][j]),这样就无法从蓝色部分得到最大相同元素子矩阵。

 把 R[i][j] 和 H[i][j] 放在一起维护也是一样的。

“Shopee杯” e起来编程暨武汉大学2020年大学生程序设计大赛(网络预选赛)D题同理。

正解代码

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 int t, n, m;
 5 char maze[2020][2020];
 6 int up[2020][2020], l[2020][2020], r[2020][2020];
 7 
 8 int main()
 9 {
10     scanf("%d", &t);
11     while(t--) {
12         scanf("%d %d", &n, &m);
13         for(int i = 1; i <= n; i++)
14             scanf("%s", maze[i]+1);
15         int ans = 1;
16         for(int i = 1; i <= n; i++) {
17             for(int j = 1; j <= m; j++)
18                 if(maze[i][j] == maze[i][j-1])
19                     l[i][j] = l[i][j-1];
20                 else
21                     l[i][j] = j;
22             for(int j = m; j > 0; j--) {
23                 if(maze[i][j] == maze[i][j+1])
24                     r[i][j] = r[i][j+1];
25                 else 
26                     r[i][j] = j;
27                 /*if(maze[i][j] == maze[i-1][j]) {
28                     up[i][j] = up[i-1][j]+1;
29                     l[i][j] = max(l[i][j], l[i-1][j]);
30                     r[i][j] = min(r[i][j], r[i-1][j]);
31                 } else {
32                     up[i][j] = 1;
33                 }
34                 ans = max(ans, min(r[i][j]-l[i][j]+1, up[i][j]));*/
35             }
36         }
37         for(int i = 1; i <= n; i++)
38             for(int j = 1; j <= m; j++)
39                 if(maze[i][j] == maze[i-1][j]) {
40                     up[i][j] = up[i-1][j]+1;
41                     l[i][j] = max(l[i][j], l[i-1][j]);
42                     r[i][j] = min(r[i][j], r[i-1][j]);
43                     ans = max(ans, min(r[i][j]-l[i][j]+1, up[i][j]));
44                 } else {
45                     up[i][j] = 1;
46                 }
47         printf("%d\n", ans);
48         /*for(int i = 1; i <= n; i++) {
49             for(int j = 1; j <= m; j++)
50                 printf("%d/%d/%d ", up[i][j], l[i][j], r[i][j]);
51             puts("");
52         }*/
53     }
54     return 0;
55 }
View Code

猜你喜欢

转载自www.cnblogs.com/canchan/p/12687180.html