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


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

    Time Limit: 5 Sec Memory Limit: 64 MB
    Submit: 459 Solved: 224
    [Submit][Status][Discuss]

    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个正方形。

    HINT

    Source

    Silver

    题意:

    有一块nn的区域,给你一些FJ的点和Bob的点,现在让你添加一个点,使FJ的点构成的正方形最大(不能添加在Bob的点上)。
    样例解释:
    这里写图片描述
    样例输入为一个6
    6的地图,橙色点为FJ的奶牛,绿色点为Bob的奶牛,白色点为未占用区域,能够成的最大正方形为 正方形ABOC ,面积为2x2=4。
    其实添加一个点能够成的最大的正方形是 正方形BCED ,面积为2x2+2x2=8,可是点E是Bob的奶牛,两头奶牛不能放在同一个点上,所以只能选择前一种方案,输出4。

    题解

    一般来说,想要构造正方形,枚举边有两种情况,一种上方,一种下方,如图:
    这里写图片描述
    枚举A,B两点的坐标,若是以A,B为正方形的边长,会枚举出两个正方形, 正方形ABCD 和 正方形ABFE ,这时就不利于我们进行很好的计算。若是以A,B为正方形的对角线呢?
    这里写图片描述
    如图,我们枚举A,B两点为 正方形ACBD 的对角线,只能画出唯一一个正方形,我们的最基本的目的达到了——保证正方形的唯一性。
    接下来,知道了A,B两点的坐标,如何得出C,D两点的坐标呢?
    通过观察,我们发现,
    A,B横坐标差=HG=HE=AE-AH;
    A,B纵坐标差=AE+BF=AE+AH;
    两式相加减后得:
    2DH=(A,B纵坐标差)+(A,B横坐标差);
    2AH=(A,B纵坐标差)-(A,B横坐标差);
    所以
    DH=CF=((A,B纵坐标差)+(A,B横坐标差))/2;
    AH=BF=((A,B纵坐标差)-(A,B横坐标差))/2;
    D点坐标即为(AX+DH,AY+AH);
    C点坐标即为(BX-CF,BY-BF);
    值得注意的是,现在C,D的坐标还没定下来,因为有可能出现另一种情况:
    这里写图片描述
    即将上一个图轴对称过来,这时按刚刚的方程得出来的是Q,R两点,并不是我们想要的正方形,这时只需要将方程变动一下就好了:
    L点坐标即为(JX+JP,JY+PL);
    I点坐标即为(KX-NK,KY-NI);
    正方形构造好了,接下来就只需要统计最大的就行了,因为FJ可以往点阵里添加一个点,所以只需要四个顶点中有>=3个点就能构造成。
    最后贴上通俗易懂的代码:

    #include<bits/stdc++.h>
    #define F(i,j,n) for(register int i=j;i<=n;i++)
    using namespace std;
    int n,s=0,ans=0,a1,a2,a3,a4,a5,a6,a7,a8;
    char a[105][105];
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    	return x*f;
    }
    inline int solve(int Sum,int Minus,char Kind){
    	if(Kind=='+')
    		return (Sum+Minus)>>1;
    	if(Kind=='-')
    		return (Sum-Minus)>>1;
    }
    int main(){
    	n=read();
    	F(i,1,n)
    		scanf("%s",a[i]+1);
    	F(i,1,n)/*枚举右下的点的横坐标*/
    		F(j,1,n)/*枚举右下的点的纵坐标*/
    			F(k,1,i)/*枚举左上的点的横坐标*/
    				F(tt,1,j){/*枚举左上的点的纵坐标*/
    					if(a[i][j]=='B'||a[k][tt]=='B')/*如果有Bob的牛就continue*/
    						continue;
    					int Sum=max(i-k,j-tt),Minus=min(i-k,j-tt);
    					if((Sum&1)!=(Minus&1))/*细节!判断奇偶性是否相同*/ 
    						continue;
    					int px=solve(Sum,Minus,'+'),py=solve(Sum,Minus,'-');/*计算出两式和与差*/
    					int p=k+px,q1=tt+py,u=i-px,v=j-py;/*得出剩下两点*/
    					if(((p-u)*(p-u)+(q1-v)*(q1-v))!=(Sum*Sum+Minus*Minus))/*考虑轴对称的情况*/
    						p=k+py,q1=tt+px,u=i-py,v=j-px;
    					if(p>=1&&q1>=1&&u>=1&&v>=1&&p<=n&&q1<=n&&u<=n&&v<=n)
    						if(a[i][j]!='B'&&a[k][tt]!='B'&&a[p][q1]!='B'&&a[u][v]!='B'){
    							s=0;
    							if(a[i][j]=='J')
    								s++;
    							if(a[k][tt]=='J')
    								s++;
    							if(a[p][q1]=='J')
    								s++;
    							if(a[u][v]=='J')
    								s++;
    							if(s>=3&&px*px+py*py>ans){
    								ans=px*px+py*py;
    								a1=i;a2=j;a3=u;a4=v;
    								a5=k;a6=tt;a7=p;a8=q1;
    							}
    						}
    				}
    	printf("%d
    ",ans);
    	//printf("
    
    %d %d
    %d %d
    %d %d
    %d %d
    ",a1,a2,a3,a4,a5,a6,a7,a8);
    	return 0;
    }
    
  • 相关阅读:
    Java自动化测试-02.编写第一个Java程序
    Java自动化测试-01.环境准备(JDK/环境变量/Intellij IDEA安装)
    eNSP 40报错(Virtualbox 0x80070005)现象与解决
    DDD初步认知
    微服务后业务系统围绕CAP的业务方案设计思考
    关于热点key读的一点思考
    Java并发——一些提高性能的方式
    Java并发——Synchronized
    dubbo学习(六)服务发布&引用
    dubbo学习(五)路由
  • 原文地址:https://www.cnblogs.com/hzf29721/p/9461204.html
Copyright © 2020-2023  润新知