输入一个N∗N的矩阵,包含J,B和*,至多再放置一个J(不能放置在B上),求用J的作顶点正方形最大面积是多少(正方形可以不与边界平行)。
每次枚举正方形两个顶点的横坐标与纵坐标,相应的得出另外两个顶点的横坐标与纵坐标。
先判断这两个点是否在地图内,然后判断这些点是否被Bob的牛占领。
如果这两个点都在地图内且没被Bob的牛占领,那么接着统计这四个点上是否是John的牛,如果有大于等于三个点是John的牛(第四个点可以是Bessie,所以是4−1=3个牛),就更新最大面积。
(x1−x2)2+(y1−y2)2
其中,(x1,y1)表示第一个顶点的坐标,(x2,y2)表示第二个顶点的坐标。
O(N4),N≤100,不超时。
#include<cstdio>
#include<cmath>//pow要用到cmath库
#define mp(x,y) if(mp[x][y]=='J')++cnt;
using namespace std;
inline int read()//快读
{
int x=0,f=1;
char s;
s=getchar();
while(s<'0'||s>'9')
{
if(s=='-')f=-f;
s=getchar();
}
while(s>='0'&&s<='9')
{
x=(x<<3)+(x<<1)+(s-48);
s=getchar();
}
return x*f;
}
const int N=101;
int n;
int ans;//ans记录最大面积
char mp[N][N];
int area(int x,int y,int x2,int y2)
{
return pow(x-x2,2)+pow(y-y2,2);//面积公式
}
int max(int x,int y)//自定义max
{
return x>y?x:y;
}
bool check(int x,int y)
{
return (x>0&&x<=n)&&(y>0&&y<=n);//判断是否在地图范围内
}
int main()
{
int i,j,k,l,x,y,x2,y2,cnt,r;
n=read();//读入
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
mp[i][j]=getchar();//读入
if(mp[i][j]=='\n')mp[i][j]=getchar();
//因为getchar()会读入换行符,所以要特判,不读入换行符。
}
}
for(i=1;i<=n;++i)//枚举第一个顶点的横坐标
{
for(j=1;j<=n;++j)//枚举第一个顶点的纵坐标
{
if(mp[i][j]!='B')//判断是否被Bob的牛占领
{
for(k=i;k<=n;++k)//枚举第二个顶点的横坐标,从i开始,避免重复计算
{
for(l=j;l<=n;++l)//枚举第二个顶点的纵坐标,从j开始,避免重复计算
{
if(mp[k][l]!='B')//判断是否被Bob的牛占领
{
cnt=0;//记录有多少个顶点被John的牛占领
x=k-l+j;//第三个顶点的横坐标
y=l+k-i;//第三个顶点的纵坐标
x2=i-l+j;//第四个顶点的横坐标
y2=j+k-i;//第四个顶点的纵坐标
if(check(x,y)&&check(x2,y2))//判断是否在地图范围内
{
if(mp[x][y]!='B'&&mp[x2][y2]!='B')//判断是否被Bob的牛占领
{
mp(i,j);//统计这个顶点是否被John的牛占领,详见第三行define
mp(k,l)//统计这个顶点是否被John的牛占领
mp(x,y);//统计这个顶点是否被John的牛占领
mp(x2,y2);//统计这个顶点是否被John的牛占领
//因为Bessie可以成为顶点之一,所以三个点符合要求就可以(4-1=3)。
if(cnt>=3)ans=max(ans,area(i,j,k,l));//更新答案
}
}
}
}
}
}
}
}
printf("%d",ans);//输出答案
return 0;
}