问题 2:Big Square(bigsq.pas)
农民 John 的牛参加了一次和农民 Bob 的牛的竞赛。他们在区域中画了一个N*N(2 <= N <=100)的正方形点阵,两个农场的牛各自占据了一些点。当然不能有两头牛处于同一个点。农场的目标是用自己的牛作为4个顶点,形成一个面积最大的正方形(不必须和边界平行) 。
除了John 的一头牛Bessie以外,John其他的牛都已经放到点阵中去了,要确定Bessie放在哪个位置,能使得农民John的农场得到一个最大的正方形(Bessie不是必须参与作为正方形的四个顶点之一)。
输入格式:
Line 1: 一个整数 N
Lines 2..N+1: 第 i+1 行描述点阵的第i行,有 N 个字符。字符集是:
'J' 表示这个点是农民 John 的牛, 'B'表示这个点是农民 Bob 的牛,
'*' 表示这个点没有被占据。保证至少有一个点没有被占据。
输入样例 (文件名bigsq.in):
6
J*J***
******
J***J*
******
**B***
******
输出格式:Line 1: 最大正方形的面积,或者无解的话输出0。
输出样例 (文件名bigsq.out):
4
输出解释:
如果 Bessie 可以占据 农民 Bob 的牛所占的点,那么可以生成一个面积为8的正方形,但是她只能放到第3行第3列,形成一个最大的、面积为 4个正方形。
枚举两个点确定一条线段作为边,再用向量旋转的方法,求出另外两个点(注意有两组解,当时忘了另外一组,所以错了一半。)
另外还可以确定一条线段作为对角线,求另外两个点(这样就只有唯一的解。但是听说有精度误差。)
可以参考一个这个:
所以说对于p = (x,y)这个向量向逆时针旋转且大小不改变所得到的向量如下:
如果是向顺时针旋转则:
注意类中传参,能用传址就传址,会快得多。
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using std::max;
char map[120][120];
long cnt = 0;
long ans = 0;
long n;
inline long getint()
{
long rs=0;bool sgn=1;char tmp;
do tmp = getchar();
while (!isdigit(tmp)&&tmp!='-');
if (tmp=='-'){tmp=getchar();sgn=0;}
do rs=(rs<<3)+(rs<<1)+tmp-'0';
while (isdigit(tmp=getchar()));
return sgn?rs:-rs;
}
struct node
{
long x;
long y;
node(){}
node(long _x,long _y):x(_x),y(_y){}
node(const node& n2):x(n2.x),y(n2.y){}
node operator-(node& n2)
{
return node(x-n2.x,y-n2.y);
}
node operator+(node& n2)
{
return node(x+n2.x,y+n2.y);
}
long operator*(node& n2)
{
return x*n2.x+y*n2.y;
}
};
node pos[10010];
#define outofrange(a) (a.x<1||a.y<1||a.x>n||a.y>n)
/*
inline bool outofrange(node& a)
{
return a.x<1||a.y<1||a.x>n||a.y>n;
}*/
inline void turn(node& n1,node& n2,node& n3,char dir)
{
node tmp = n2-n1;
n3.y = tmp.x;
n3.x = tmp.y;
if (dir)
{
if (tmp.x > 0 && tmp.y > 0)
n3.x = -n3.x;
else if (tmp.x > 0 && tmp.y < 0)
n3.y = -n3.y;
else if (tmp.x < 0 && tmp.y < 0)
n3.x = -n3.x;
else if (tmp.x < 0 && tmp.y > 0)
n3.y = -n3.y;
else if (tmp.x == 0)
n3.x = -n3.x;
else if (tmp.y == 0)
n3.y = n3.y;
}
else
{
if (tmp.x > 0 && tmp.y > 0)
n3.y = -n3.y;
else if (tmp.x > 0 && tmp.y < 0)
n3.x = -n3.x;
else if (tmp.x < 0 && tmp.y < 0)
n3.y = -n3.y;
else if (tmp.x < 0 && tmp.y > 0)
n3.x = -n3.x;
else if (tmp.x == 0)
n3.x = n3.x;
else if (tmp.y == 0)
n3.y = -n3.y;
}
n3 = n3 + n1;
}
node tn; node fn;
int main()
{
freopen("bigsq.in","r",stdin);
freopen("bigsq.out","w",stdout);
n = getint();
for (long i=1;i<n+1;i++)
{
for (long j=1;j<n+1;j++)
{
do map[i][j]=getchar();
while (map[i][j]!='J'&&map[i][j]!='*'&&map[i][j]!='B');
if (map[i][j] == 'J')
{
++cnt;
pos[cnt].x = i;
pos[cnt].y = j;
}
}
}
for (long i=1;i<cnt+1;i++)
{
for (long j=i+1;j<cnt+1;j++)
{
tn = (pos[i]-pos[j]);
long square = tn.x*tn.x+tn.y*tn.y;
if (square <= ans)
continue;
turn(pos[j],pos[i],tn,0);
turn(pos[i],pos[j],fn,1);
if (map[tn.x][tn.y]!='B' && map[fn.x][fn.y]!='B' && (map[tn.x][tn.y]=='J'||map[fn.x][fn.y]=='J') && !outofrange(tn) && !outofrange(fn))
{
ans = max(ans,square);
//printf("a%ld(%ld,%ld),%ld(%ld,%ld),(%ld,%ld),(%ld,%ld),ans:%ld\n",i,pos[i].x,pos[i].y,j,pos[j].x,pos[j].y,tn.x,tn.y,fn.x,fn.y,ans);
}
turn(pos[j],pos[i],tn,1);
turn(pos[i],pos[j],fn,0);
if (map[tn.x][tn.y]!='B' && map[fn.x][fn.y]!='B' && (map[tn.x][tn.y]=='J'||map[fn.x][fn.y]=='J') && !outofrange(tn) && !outofrange(fn))
{
ans = max(ans,square);
//printf("b%ld(%ld,%ld),%ld(%ld,%ld),(%ld,%ld),(%ld,%ld),ans:%ld\n",i,pos[i].x,pos[i].y,j,pos[j].x,pos[j].y,tn.x,tn.y,fn.x,fn.y,ans);
}
}
}
printf("%ld",ans);
return 0;
}