• 洛谷 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;}
        }
    }
     
  • 相关阅读:
    [USACO12FEB]牛券Cow Coupons
    合并果子
    序列合并
    中位数
    道路游戏
    教主的花园
    摆花
    hello world之Makefile
    mysql+tomcat+spring 配置心得(从0开始搭环境)
    C#,.Net自动生成大写字母编码
  • 原文地址:https://www.cnblogs.com/yanyiming10243247/p/9238558.html
Copyright © 2020-2023  润新知