三角蛋糕
Description
XP在机房里放了一块正三角形的大蛋糕,但是第二天他发现蛋糕被老鼠咬坏了。
XP不想让蛋糕白白的被浪费,于是他把蛋糕分割成了一个个的小正三角形(如上图所示)。
黑色的小正三角形表示老鼠把那一块咬坏了。
XP想要切出一块最大的没被老鼠咬坏正三角形的蛋糕,可是最大的三角形有多大呢?
Input
第一行,一个整数
N
,表示XP把蛋糕纵向划分为
接下来的
N
行,第
“-”表示这块蛋糕是好的,“#”表示这块蛋糕被咬坏了。
为了保持三角形的形状,输入文件中会出现空格。
Output
一行一个整数,表示最大的三角形包括的小三角形数。
Sample Input
5
#-##----#
-----#-
---#-
-#-
-
Sample Output
9
Data Size
对于
30%
的数据,满足
n≤5
对于所有的测试数据,满足
n≤100
。
Solution
f1[i][j]=Min(f1[i+1][j−1],f1[i+1][j+1])
f2[i][j]=Min(f2[i−1][j−1],f2[i−1][j+1])
其中 f1[i][j] 表示往下走的最大长度, f2[i][j] 表示往上走的最大长度。
注意当 s[i+1][j]= “#” 时, f1[i][j]=1 ,
当 s[i−1][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;
}