博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

bzoj:1661 [Usaco2006 Nov]Big Square 巨大正方形

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***
******

Sample Output

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\n",ans);
}

简洁明快的西瓜风格

 
posted @ 2015-11-25 14:20  swm_sxt  阅读(278)  评论(0编辑  收藏  举报