【题解】2014 螺旋矩阵(P2239)

来源:互联网 发布:大逃杀游戏知乎 编辑:程序博客网 时间:2024/05/20 16:42

原题链接

算法分析

初次见到本题,第一个想到的思路肯定是一个一个地推,然后开个二维数组存起来,但是题目末尾的数据范围告诉我们这种方法显然是不现实的。本题解法有很多,但是要学会推导,先来看看 4×45×56×6 的螺旋矩阵。
看得粗来这是便笺
从上述三个矩阵中,不难发现以下规律:

f[1][i]=i ;

f[n][i]=n+i1 ;

n2=n+(n1)×2+(n2)×2++1×2

我的方法是一条线一条线地搜,拿变量来存当前的方位和数字,以 6×6 的螺旋矩阵为例,行进方向如下图所示:
这里写图片描述
每当一条线的行或列与已知点的行或列相同时,就可以通过运算得到已知点的数。行列改变时的运算可以通过 ±1 来控制,代码实现起来还是比较容易的,交上去也是 0ms

示例代码

#include <bits/stdc++.h>using namespace std;int n, x, y, f1[2] = { -1, 1 }, f2[2] = { 1, -1 };//用x,y表示目标方位,s表示当前数字,f1,f2数组控制方向int main(){    scanf ( "%d %d %d", &n, &x, &y );    if ( x == 1 ){        printf ( "%d\n", y );        return 0;    }    if ( y == n ){        printf ( "%d\n", n + x - 1 );        return 0;    }//上来就先双特判(打表),用上之前推导出的公式    int i = 1, j = n, s = n;//初始化,i和j表示当前方位,s表示当前数字    for ( int k = 1; k < n; k++ ){        for ( int p = 1; p <= 2; p++ ){//因为要加上同一个数2次            s += n - k;//当前数字加上一条线            if ( p == 1 ) i += f1[k % 2] * ( n - k );            //偶数相当于向上i要减去,奇数则反之            else j += f2[k % 2] * ( n - k );            //偶数相当于向右j要加上,奇数则反之            if ( i == x ){//当行相同时,当前数字加上两列之差的绝对值。                printf ( "%d\n", s + abs ( y - j ) );                return 0;//符合条件直接输出结束            }            else if ( j == y ){            //当列相同时,当前数字加上两行之差的绝对值。                printf ( "%d\n", s + abs ( x - i ) );                return 0;//同上            }        }    }}
原创粉丝点击