uva 1330 City Game

点击打开链接uva 1330


思路:悬线法求解最大子矩阵
分析:
1 详细资料请见点击打开链接
2 有个地方需要注意的是输入格式,有可能输入字母后面会有多个空格,所以必须要过滤掉这些空格

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 1010;
int mat[MAXN][MAXN];
int up[MAXN][MAXN] , Left[MAXN][MAXN] , Right[MAXN][MAXN];
int n , m;

int solve(){
    int ans = 0;
    int leftNum , rightNum;
    for(int i = 1 ; i <= n ; i++){
       //从左往右求最大的左边列编号
       leftNum = 0;
       for(int j = 1 ; j <= m ; j++){
          if(!mat[i][j]){
             up[i][j] = 0; 
             Left[i][j] = 0;
             leftNum = j;
          }
          else{
             up[i][j] = i == 1 ? 1 : up[i-1][j]+1;   
             Left[i][j] = i == 1 ? leftNum+1 : max(Left[i-1][j] , leftNum+1); 
          } 
       }
       //从右往左求最小的右边列编号
       rightNum = m+1;
       for(int j = m ; j >= 1 ; j--){
          if(!mat[i][j]){ 
             Right[i][j] = m+1; 
             rightNum = j;
          }
          else{
             Right[i][j] = i == 1 ? rightNum-1 : min(Right[i-1][j] , rightNum-1);
             ans = max(ans , up[i][j]*(Right[i][j]-Left[i][j]+1));
          }
       }
    }
    return 3*ans;
}

int main(){
    int Case;
    char c;
    scanf("%d" , &Case);
    while(Case--){
        scanf("%d%d" , &n , &m);
        for(int i = 1 ; i <= n ; i++){
           for(int j = 1 ; j <= m ; j++){
               c = getchar();
               while(c != 'F' && c != 'R')
                   c = getchar();
               mat[i][j] = c == 'F' ? 1 : 0;
           }
        }
        printf("%d\n" , solve()); 
    }
    return 0;
}



你可能感兴趣的:(game)