Description
农民 John 的牛参加了一次和农民 Bob 的牛的竞赛。他们在区域中画了一个N*N 的正方形点阵,两个农场的牛各自占据了一些点。当然不能有两头牛处于同一个点。农场的目标是用自己的牛作为4个顶点,形成一个面积最大的正方形(不必须和边界平行) 。 除了 Bessie 以外,FJ其他的牛都已经放到点阵中去了,要确定bessie放在哪个位置,能使得农民约翰的农场得到一个最大的正方形(Bessie不是必须参与作为正方形的四个顶点之一)。
Input
* Line 1: 一个整数 N,2<=N<=100
* Lines 2..N+1: 第 i+1 行描述点阵的第i行,有 N 个字符。字符集是: 'J' 表示这个点是农民 John 的牛, 'B'表示这个点是农民 Bob 的牛, '*' 表示这个点没有被占据。保证至少有一个点没有被占据。
Output
* Line 1: 最大正方形的面积,或者无解的话输出0。
Sample Input
6
J*J***
******
J***J*
******
**B***
******
J*J***
******
J***J*
******
**B***
******
Sample Output
4
输出解释:
如果 Bessie 可以占据 农民 Bob 的牛所占的点,那么可以生成一个面积为8
的正方形,但是她只能放到第3行第3列,形成一个最大的、面积为 4个正方形。
输出解释:
如果 Bessie 可以占据 农民 Bob 的牛所占的点,那么可以生成一个面积为8
的正方形,但是她只能放到第3行第3列,形成一个最大的、面积为 4个正方形。
O(n^4)直接枚举2个点……就行了,但是记得枚举完最好上下都扩展一遍
第一次A是1000+MS,非常不爽,于是就各种剪枝,剪出了316MS,成功挤进前五
交了8次,表吐槽……
#include<cmath> #include<cstdio> #include<algorithm> using namespace std; int n,m,ans=0,an; char map[100][100]; int main(){ scanf("%d",&n); for (int i=0;i<n;i++) for (int j=0;j<n;j++) while(map[i][j]!='J'&&map[i][j]!='*'&&map[i][j]!='B') map[i][j]=getchar(); for (int x1=0;x1<n;x1++) for (int y1=0;y1<n;y1++){ if ((n-1-x1)*(n-1-x1)+(n-1-y1)*(n-1-y1)<=ans) break; for (int x2=x1;x2<n;x2++) for (int y2=y1+int(sqrt((ans-(x2-x1)*(x2-x1))>0?(ans-(x2-x1)*(x2-x1)):0));y2<n;y2++) if (x1!=x2||y1!=y2) if (map[x1][y1]=='J'&&map[x2][y2]=='J'){ an=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1); if (ans>=an) continue; if(!((x1-(y2-y1)<0)||(y1+(x2-x1)>=n)||(map[x1-(y2-y1)][y1+(x2-x1)]=='B')||(x2-(y2-y1)<0)||(y2+(x2-x1)>=n)||(map[x2-(y2-y1)][y2+(x2-x1)]=='B')||(map[x1-(y2-y1)][y1+(x2-x1)]=='*'&&map[x2-(y2-y1)][y2+(x2-x1)]=='*')))ans=an; if(!((x1+(y2-y1)>=n)||(y1-(x2-x1)<0)||(map[x1+(y2-y1)][y1-(x2-x1)]=='B')||(x2+(y2-y1)>=n)||(y2-(x2-x1)<0)||(map[x2+(y2-y1)][y2-(x2-x1)]=='B')||(map[x1+(y2-y1)][y1-(x2-x1)]=='*'&&map[x2+(y2-y1)][y2-(x2-x1)]=='*')))ans=an; } } printf("%d ",ans); }
简洁明快的西瓜风格