题目:链接

题意

给定一个字符矩阵,找到矩阵中的最大正方形。

思路

关键在于如何确定一个正方形。枚举正方形的四个顶点,有8层for循环,显然不可取。所以根据正方形的特点,只需要枚举正方形的对角线的两个顶点,只需要4层for循环。确定好正方形以后,就是寻找最大的正方形,根据几何知识,边长(对角线)越长,正方形越大,所以只需比较每次找到的正方形的边长(对角线)即可。

心得

读取一个整数及矩阵的时候,要统一用cin或者scanf,不能一个cin一个scanf,会出错。

在枚举的过程中,枚举一个顶点就判断一下是否符合要求,再进入下一步,会减少不必要的枚举次数。

如何通过两个顶点的坐标计算出另外两个顶点的坐标,算法入门课中讲的是找到对角线上的两个顶点,但是寻找相邻两个顶点再去计算另外两个顶点会简单些,避免了小数。计算得到的新顶点还要判断一下是否再原来的字符矩阵中,计算方式如下:

x3=x1+y2-y1;
y3=y1-(x2-x1);
x4=x2+y2-y1;
y4=y2-(x2-x1);

代码

using namespace std;

int n;
char ch[110][110];
int ans[4][2];

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>ch[i][j];
    int x1,y1,x2,y2,x3,y3,x4,y4;
    double len,maxx=0;
    for(x1=1;x1<=n;x1++)
        for(y1=1;y1<=n;y1++)
            if(ch[x1][y1]=='#')
                for(x2=1;x2<=n;x2++)
                    for(y2=1;y2<=n;y2++)
                        if(ch[x2][y2]=='#')
                        {
                            x3=x1+y2-y1;
                            y3=y1-(x2-x1);
                            x4=x2+y2-y1;
                            y4=y2-(x2-x1);
                            if(x3>=1&&x3<=n&&x4>=1&&x4<=n&&y3>=1&&y3<=n&&y4>=1&&y4<=n)
                                if(ch[x3][y3]=='#'&&ch[x4][y4]=='#')
                                {
                                    len=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
                                    if(len>maxx)
                                    {
                                        maxx=len;
                                        ans[0][0]=x1;
                                        ans[0][1]=y1;
                                        ans[1][0]=x2;
                                        ans[1][1]=y2;
                                        ans[2][0]=x3;
                                        ans[2][1]=y3;
                                        ans[3][0]=x4;
                                        ans[3][1]=y4;
                                    }
                                }
                        }
    
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<2;j++)
            cout<<ans[i][j]<<' ';
        cout<<endl;
    }    
    return 0;
}