螺旋矩阵

螺旋矩阵

题目描述

一个n行n列的螺旋矩阵可由如下方法生成:
从矩阵的左上角(第1行第1列)出发,初始时向右移动;如果前方是未曾经过的格子,则继续前进,否则右转;重复上述操作直至经过矩阵中所有格子。根据经过顺序,在格子中依次填入1,2,3,...,n2,便构成了一个螺旋矩阵。
下图是一个n=4时的螺旋矩阵。

现给出矩阵大小n以及i和j,请你求出该矩阵中第i行第j列的数是多少。

输入

输入共一行,包含三个整数 n,i,j,每两个整数之间用一个空格隔开,分别表示矩阵大小、待求的数所在的行号和列号。
1≤n≤30000,1≤i≤n,1≤j≤n

输出

输出共一行,包含一个整数,表示相应矩阵中第i行第j列的数。

样例输入

4 2 3

样例输出

14
分析:
     如果直接模拟会占用很多内存,而且时间复杂度会很高(n^2);
     换个思路,将矩阵从外向内一层层剥开,设矩阵边长为n,最外一层有(n-1)*4个数,第二层有(n-3)*4个数,假设剥了x层,我们可以先求出剥出的元素数量,即剥出数中最大的数,然后再判断所求的点在剩余正方形的哪条边(上下左右),在顺时针判断剩余正方形边上从左上角的元素到所求的元素的个数,与前面剥出的数相加,即为该点的数。
(也不知道有没有人能看懂)
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
    int side=0,m,u,d,r,l,n,x,y,ans=0;
    scanf("%d%d%d",&n,&x,&y);
    side = min(min(x,y),min(n-x+1,n-y+1));         //需要剥出的层数
    if(side==x&&side==y&&n%2==1) {                 //如果要求的元素n阶矩阵正中心 值为n^2;
        printf("%d\n",n*n);
        return 0;
    }
    m=n;
    for(int i=1;i<side;i++){                       //剥出的个数
        ans+=(m-1)*4;
        m-=2;
    }
    u=x,d=n-x+1,l=y,r=n-y+1;                       //元素所在的边有上下左右,情况讨论
    if(u<d&&u<=l&&u<=r){                           //根据对应关系求剩余正方形边上顺时针到所求元素的元素个数
        ans+=(y-side+1);                           //与之前的剥出个数相加求和即为所求
        printf("%d\n",ans);                        //对应关系画画图就出来了
    }                                              
    else if(r<d&&r<u&&r<l){
        ans+=m;
        ans+=(x-side);
        printf("%d\n",ans);
    }
    else if(d<u&&d<=l&&d<=r){
        ans+=(m-1)*2;
        ans+=(m-(y-side));
        printf("%d\n",ans);
    }
    else {
        ans+=(m-1)*3+1;
        ans+=(m-(x-side)-1);
        printf("%d\n",ans);
    }
    return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值