码迷,mamicode.com
首页 > 其他好文 > 详细

uvalive 3029 City Game

时间:2017-10-03 14:33:56      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:while   上拉   getchar   printf   最大的   else   tps   getch   int   

https://vjudge.net/problem/UVALive-3029

题意:

给出一个只含有F和R字母的矩阵,求出全部为F的面积最大的矩阵并且输出它的面积乘以3。

思路:

求面积最大的子矩阵,可以用扫描线。参考训练指南(orz,虽然并不知道为什么用扫描线)。

对于每一个格子包含F,我们可以把它向上拉成一条悬线,直到上面的格子为R,然后观察这条悬线可以扫到左边与右边的最大距离,那么我们所求的面积就是所有的悬线中 悬线的长度乘以(右边界 - 左边界 + 1)的最大值。

然后,需要计算悬线的长度,用up来表示,那么当这个格子为F时up(i,j) = up(i - 1,j) + 1(i >= 1),up(i,j) = 1,(i == 0);

当这个格子为R时,up(i,j) = 0。

然后,用left数组和right数组维护左右边界的信息:

我们假设lo是当前格子之前的最近的是R的格子,从左往右遍历,那么 lo 的初值是-1,那么当(i,j) 为 F时 ,left(i,j) = max(left(i-1,j),lo + 1),为什么呢,因为当前的悬线如果是包含上一行此列的格子的话,那么就要考虑上一行左边的情况了;

当(i,j)为R时,left(i,j) = 0。

维护右边界的信息同理,不同的是求最小值和从右往左遍历。

!!!:记住一边遍历,一边维护。输入也是坑!

代码:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <algorithm>
  4 using namespace std;
  5 
  6 char a[1005][1005];
  7 int up[1005][1005],right[1005][1005],left[1005][1005];
  8 
  9 int main()
 10 {
 11     int t;
 12 
 13     scanf("%d",&t);
 14 
 15     while(t--)
 16     {
 17         int m,n;
 18 
 19         memset(a,0,sizeof(a));
 20         memset(up,0,sizeof(up));
 21         memset(right,0,sizeof(right));
 22         memset(left,0,sizeof(left));
 23 
 24         scanf("%d%d",&m,&n);
 25 
 26         getchar();
 27 
 28         for (int i = 0;i < m;i++)
 29             for (int j = 0;j < n;j++)
 30         {
 31             char s;
 32 
 33             s = getchar();
 34 
 35             while (s != R && s != F) s = getchar();
 36 
 37             if (s == R) a[i][j] = 0;
 38             else a[i][j] = 1;
 39         }
 40 
 41         /*for (int i= 0;i < m;i++)
 42         {
 43             for (int j = 0;j < n;j++) printf("%d",(int)a[i][j]);
 44 
 45             printf("\n");
 46         }*/
 47 
 48         int ans = 0;
 49 
 50         for (int i = 0;i < m;i++)
 51         {
 52             for (int j = 0;j < n;j++)
 53             {
 54                 if (i == 0)
 55                 {
 56                     up[i][j] = a[i][j];
 57                 }
 58                 else
 59                 {
 60                     if (a[i][j]) up[i][j] = up[i-1][j] + 1;
 61                     else up[i][j] = 0;
 62                 }
 63             }
 64 
 65             int lo = -1,ro = n;
 66 
 67             if (i == 0)
 68             {
 69                 for (int j = 0;j < n;j++)
 70                 {
 71                     if (a[i][j] == 0) left[i][j] = 0, lo = j;
 72                     else left[i][j] = lo + 1;
 73                 }
 74 
 75                 for (int j = n - 1;j >= 0;j--)
 76                 {
 77                     if (a[i][j] == 0) right[i][j] = n, ro = j;
 78                     else right[i][j] = ro - 1;
 79                 }
 80 
 81                 for (int j = 0;j < n;j++)
 82                 {
 83                     int tmp = up[i][j] * (right[i][j] - left[i][j] + 1);
 84 
 85                     ans = max(ans,tmp * 3);
 86                 }
 87             }
 88             else
 89             {
 90                 for (int j = 0;j < n;j++)
 91                 {
 92                     if (a[i][j] == 0) left[i][j] = 0, lo = j;
 93                     else left[i][j] = max(lo + 1,left[i-1][j]);
 94                 }
 95 
 96                 for (int j = n - 1;j >= 0;j--)
 97                 {
 98                     if (a[i][j] == 0) right[i][j] = n, ro = j;
 99                     else right[i][j] = min(ro - 1,right[i-1][j]);
100                 }
101 
102                 for (int j = 0;j < n;j++)
103                 {
104                     int tmp = up[i][j] * (right[i][j] - left[i][j] + 1);
105 
106                     ans = max(ans,tmp * 3);
107                 }
108             }
109         }
110 
111         /*for (int i = 0;i < m;i++)
112         {
113             for (int j = 0;j < n;j++)
114             {
115                 printf("%d %d %d\n",up[i][j],left[i][j],right[i][j]);
116             }
117         }*/
118 
119         printf("%d\n",ans);
120     }
121 
122     return 0;
123 }

 

uvalive 3029 City Game

标签:while   上拉   getchar   printf   最大的   else   tps   getch   int   

原文地址:http://www.cnblogs.com/kickit/p/7623700.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!