洛谷 P2867 [USACO06NOV]大广场Big Square

题目描述

Farmer John's cows have entered into a competition with Farmer Bob's cows. They have drawn lines on the field so it is a square grid with N × N points (2 ≤ N ≤ 100), and each cow of the two herds has positioned herself exactly on a gridpoint. Of course, no two cows can stand in the same gridpoint. The goal of each herd is to form the largest square (not necessarily parallel to the gridlines) whose corners are formed by cows from that herd.

All the cows have been placed except for Farmer John's cow Bessie. Determine the area of the largest square that Farmer John's cows can form once Bessie is placed on the field (the largest square might not necessarily contain Bessie).

农民 John 的牛参加了一次和农民 Bob 的牛的竞赛。他们在区域中画了一个N*N 的正方形点阵,两个农场的牛各自占据了一些点。当然不能有两头牛处于同一个点。农场的目标是用自己的牛作为4个顶点,形成一个面积最大的正方形(不必须和边界平行) 。 除了 Bessie 以外,FJ其他的牛都已经放到点阵中去了,要确定bessie放在哪个位置,能使得农民约翰的农场得到一个最大的正方形(Bessie不是必须参与作为正方形的四个顶点之一)。

输入输出格式

输入格式:

 

Line 1: A single integer, N

Lines 2..N+1: Line i+1 describes line i of the field with N characters. The characters are: 'J' for a Farmer John cow, 'B' for a Farmer Bob cow, and '*' for an unoccupied square. There will always be at least one unoccupied gridpoint.

 

输出格式:

 

Line 1: The area of the largest square that Farmer John's cows can form, or 0 if they cannot form any square.

 

输入输出样例

输入样例#1: 复制
6
J*J***
******
J***J*
******
**B***
******
输出样例#1: 复制
4
思路:暴力枚举对角线上的两个点,然后计算出中点坐标。
然后可以根据平面向量计算出其余的两个对角线的坐标。
判断是否合法即可,如果可以就取最大值。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 10000
using namespace std;
char s[110];
int n,num,ans;
int map[110][110];
struct nond{
    double x,y;
}cnt[MAXN];
bool dint(double x,int y){
    return y-0.001<=x and x<=y+0.001;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",s+1);
        for(int j=1;j<=n;j++){
            if(s[j]=='B')    map[i][j]=1;
            else if(s[j]=='J'){
                map[i][j]=2;
                cnt[++num].x=i;
                cnt[num].y=j;
            }
        }
    }
    for(int i=1;i<=num;i++)
        for(int j=i+1;j<=num;j++){
            double midx=(cnt[i].x+cnt[j].x)/2.0;//中点 
            double midy=(cnt[i].y+cnt[j].y)/2.0;//中点 
            double mx=(cnt[i].x-cnt[j].x)/2.0;  //向量 
            double my=(cnt[i].y-cnt[j].y)/2.0;    //向量 
            double dx=midx+(-my);
            double dy=midy+mx;
            if(dx<1||dx>n)    continue;
            if(dy<1||dy>n)    continue;
            double wx=midx+my;
            double wy=midy+(-mx);
            if(wx<1||wx>n)    continue;
            if(wy<1||wy>n)    continue;
            if(dx==wx&&dy==wy)    continue;
            int ax=int(dx+0.5),ay=int(dy+0.5);
            int bx=int(wx+0.5),by=int(wy+0.5);
            if(!dint(dx,ax))    continue;
            if(!dint(dy,ay))    continue;
            if(!dint(wx,bx))    continue;
            if(!dint(wy,by))    continue;
            if(map[ax][ay]==1||map[bx][by]==1)    continue;
            if(!map[ax][ay]&&!map[bx][by])    continue;
            int S=(dx-cnt[i].x)*(dx-cnt[i].x)+(dy-cnt[i].y)*(dy-cnt[i].y);
            ans=max(ans,S);
        }
    cout<<ans;
}

 

 
posted @ 2017-11-07 17:25  一蓑烟雨任生平  阅读(332)  评论(0编辑  收藏  举报