您的位置:首页 > 其它

三角蛋糕

2016-06-27 17:25 543 查看

三角蛋糕

Description

XP在机房里放了一块正三角形的大蛋糕,但是第二天他发现蛋糕被老鼠咬坏了。



XP不想让蛋糕白白的被浪费,于是他把蛋糕分割成了一个个的小正三角形(如上图所示)。

黑色的小正三角形表示老鼠把那一块咬坏了。

XP想要切出一块最大的没被老鼠咬坏正三角形的蛋糕,可是最大的三角形有多大呢?

Input

第一行,一个整数 N,表示XP把蛋糕纵向划分为 N 行。

接下来的 N 行,第 i 行包括了 (n−i)∗2+1 个有效字符。

“-”表示这块蛋糕是好的,“#”表示这块蛋糕被咬坏了。

为了保持三角形的形状,输入文件中会出现空格。

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: