洛谷 2239 螺旋矩阵

洛谷 2239 螺旋矩阵

翻了翻题解,发现我的这个方法好像并没有被写过,也许是这个方法太菜了,但是还是可以AC的。

首先呢:1 ≤ n ≤ 30,000.....暴力就别想了,最多50分

于是就开始在暴力的基础上找方法,无意发现,如果我们开始先将矩阵一层一层的剥开,直到目标位置在新矩阵的最外层是停止。此时最坏情况,目标点在30000X30000矩阵的的(2,1)位置(如果搜索方向不同可能会不一样,但结论相同),我们也只需循环填120000-4个数就可以找到答案。

重要的是“剥开”矩阵的过程,先贴代码:

int c=min(min(x-1,n-x),min(y-1,n-y));//确定要剥开的层数
    while(c--)
    {
        ans+=n*n-(n-2)*(n-2);     //记录剥掉的数字总数
        n-=2;                     //原矩阵边长减2
        --x;--y;                  //目标位置也随之变化
    }

另外我们也不必真正的将数字填上,用tot记录好填到哪个数了,到时候输出tot与前面算出ans的和即可。

而且由于我们已经保证目标点在新矩阵的最外层,所以不避开任何数组进行记录,填数时撞到边界就转向。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,x,y,tot=1,i=1,j=0;
long long ans=0;
bool pd(int xx,int yy)
{
    if(xx==x&&yy==y) 
    {
        cout<<tot+ans-1;
        return 1;
    }
    return 0;
}
int main()
{
    scanf("%d%d%d",&n,&x,&y);
    int c=min(min(x-1,n-x),min(y-1,n-y));//确定要剥开的层数
    while(c--)
    {
        ans+=n*n-(n-2)*(n-2);     //记录剥掉的数字总数
        n-=2;                     //原矩阵边长减2
        --x;--y;                  //目标位置也随之变化
    }
    while(tot<=n*n)
    {
        while(j+1<=n) {++j;++tot;if(pd(i,j)) return 0;}
        while(i+1<=n) {++i;++tot;if(pd(i,j)) return 0;}
        while(j-1>=1) {--j;++tot;if(pd(i,j)) return 0;}
        while(i-1>=1) {--i;++tot;if(pd(i,j)) return 0;}
    }
}
 
原文地址:https://www.cnblogs.com/yanyiming10243247/p/9238558.html