【枚举】Big Square

来源:互联网 发布:温州藤桥网络问政 编辑:程序博客网 时间:2024/05/17 23:49

问题 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)这个向量向逆时针旋转且大小不改变所得到的向量如下:

p: (x,y) --------> p': ( x*cos(d)-y*sin(d) , x*sin(d)+y*cos(d) )


如果是向顺时针旋转则:

p: (x,y) --------> p': ( x*cos(-d)-y*sin(-d) , x*sin(-d)+y*cos(-d) )



注意类中传参,能用传址就传址,会快得多。

#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;}