三角蛋糕

69 篇文章 0 订阅

三角蛋糕


Description

XP在机房里放了一块正三角形的大蛋糕,但是第二天他发现蛋糕被老鼠咬坏了。
这里写图片描述
XP不想让蛋糕白白的被浪费,于是他把蛋糕分割成了一个个的小正三角形(如上图所示)。
黑色的小正三角形表示老鼠把那一块咬坏了。
XP想要切出一块最大的没被老鼠咬坏正三角形的蛋糕,可是最大的三角形有多大呢?


Input

第一行,一个整数 N ,表示XP把蛋糕纵向划分为 N 行。
接下来的 N 行,第 i 行包括了 (ni)2+1 个有效字符。
“-”表示这块蛋糕是好的,“#”表示这块蛋糕被咬坏了。
为了保持三角形的形状,输入文件中会出现空格。


Output

一行一个整数,表示最大的三角形包括的小三角形数。


Sample Input

5
#-##----#
 -----#-
  ---#-
   -#-
    -

Sample Output

9


Data Size

对于 30% 的数据,满足 n5
对于所有的测试数据,满足 n100


Solution

f1[i][j]=Min(f1[i+1][j1],f1[i+1][j+1])
f2[i][j]=Min(f2[i1][j1],f2[i1][j+1])

其中 f1[i][j] 表示往下走的最大长度, f2[i][j] 表示往上走的最大长度。
注意当 s[i+1][j]= “#” 时, f1[i][j]=1
s[i1][j]= “#” 时, f2[i][j]=1


Code

#include <iostream>
#include <cstdio>
#include <cstring>

#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))

using namespace std;

int n,ans;
char s[410][410];
int f1[410][410];
int f2[410][410];

void dp1(int x,int y){
    if(s[x][y]=='#'){
        f1[x][y]=0;
        return;
    }
    if(f1[x][y]!=-1)return;
    if(x==n){
        f1[x][y]=1;
        return;
    }
    if(s[x+1][y]=='#'){
        f1[x][y]=1;
        return;
    }
    if(y!=x+1){dp1(x+1,y-1);f1[x][y]=f1[x+1][y-1]+1;}
    if(y!=2*n-x-1){
        dp1(x+1,y+1);
        if(f1[x][y]==-1)f1[x][y]=f1[x+1][y+1]+1;
        else f1[x][y]=Min(f1[x][y],f1[x+1][y+1]+1);
    }
    if(y==x+1||y==2*n-x-1)f1[x][y]=1;
}

void dp2(int x,int y){
    if(s[x][y]=='#'){
        f2[x][y]=0;
        return;
    }
    if(f2[x][y]!=-1)return;
    if(x==1){
        f2[x][y]=1;
        return;
    }
    if(s[x-1][y]=='#'){
        f2[x][y]=1;
        return;
    }
    dp2(x-1,y-1);dp2(x-1,y+1);
    f2[x][y]=Min(f2[x-1][y+1]+1,f2[x-1][y-1]+1);
}

int main(){

    freopen("trigon.in","r",stdin);
    freopen("trigon.out","w",stdout);

    memset(f1,-1,sizeof f1);
    memset(f2,-1,sizeof f2);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        getchar();
        for(int j=2;j<=i;j++)getchar();
        for(int j=i;j<=2*n-i;j++)s[i][j]=getchar();
    }
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=2*n-i;j+=2){
            dp1(i,j);dp2(i,j-1);
            ans=Max(ans,f1[i][j]);
            ans=Max(ans,f2[i][j-1]);
        }
        dp2(i,2*n-i);
        ans=Max(ans,f2[i][2*n-i]);
    }
    printf("%d\n",ans*ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值