[NOIP普及组2014第三题]螺旋矩阵

螺旋矩阵##


题目描述
一个n行n列的螺旋矩阵可由如下方法生成:

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

下图是一个n = 4 时的螺旋矩阵。

1 2 3 4

12 13 14 5

11 16 15 6

10 9 8 7

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

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

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

输入样例
4 2 3
输出样例
14
【数据说明】
对于50%的数据,1 ≤ n ≤ 100;
对于100%的数据,1 ≤ n ≤ 30,000,1 ≤ i ≤ n,1 ≤ j ≤ n。

其实本题很简单,你只要打几个螺旋矩阵,然后就可以找出规律,例如:
1 2 3
8 9 4
7 6 5

然后我们把n=3的矩阵嵌入到n=5的矩阵里面:
1 2 3 4 5
16 1 2 3 6
15 8 9 4 7
14 7 6 5 8
13 12 11 10 9
对比原来的n=5的中间的内矩阵:
17 18 19
24 25 26
23 22 21
天啊,你有没有发现其实这就是n=3的矩阵每个数加上16(我们称为k)!
巧合?不信的话你可以再打出n=2和n=4的矩阵作对比,你就会发现k=n*4-4
内矩阵搞定了,你就可以发现外矩阵也有规律:

当x1或者yn时,结果就是x+y-1
当xn或者y1时,结果就是4*n-x-y-1

开始我本来想用DP的,可是数据不允许.....无奈之下只好用递归了。。。
附代码:

#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
int turn(int n,int x,int y)
{
    if(x==1||y==n)return x+y-1;
    else if(x==n||y==1)return 4*n-x-y-1;
    else
    {
        return turn(n-2,x-1,y-1)+n*4-4;//每次就是n-2的矩阵+k
    }
}
int main()
{
    int n,x,y;
    scanf("%d%d%d",&n,&x,&y);
    printf("%d",turn(n,x,y)); 
    return 0;
}
原文地址:https://www.cnblogs.com/candy067/p/11402009.html