• 【NOIP2014 普及组】螺旋矩阵


    【NOIP2014 普及组】螺旋矩阵

    一、题目

    【NOIP2014 普及组】螺旋矩阵

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 18  解决: 0
    [提交][状态][讨论版]

    题目描述

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

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

    下图是一个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.老老实实填数组。(此方法简单易懂,但当矩阵过大时,就会出现数组开不够大,或long long也不够的情况)

    2. 用算法找规律,但规律不是一般的难找。我就简单说说我找到的规律。

     

     

     

    1

    2

    3

    4

    12

    13

    14

    5

    11

    16

    15

    6

    10

    9

    8

    7

     

    1

    2

    4

    3

     

    首先对比两表,你就会发现下表就是上表中间四格每个减去12,正好就是外圈12个数中最大的;

    而12就是外圈边长的4倍减4;

    于是,就成了这样

    1

    2

    3

    4

    12

    1

    2

    5

    11

    3

    4

    6

    10

    9

    8

    7

    红色是内圈,黑色是外圈

    红色基数为12,黑色基数为0

     

    同时,每一圈最上方的一行就是i+j-1的值。

    最右方的一列就是i+j-1的值。

    最下方的一行就是4n-i-j-1的值。

    最左方的一列就是4n-i-j-1的值。

    (一定要记得加上外圈基数哦!)

    DP思路

    状态:

    用f[n][i][j]表示n阶方块i,j位置的值。

    对于外圈的:

    i表示列,j表示行

    if(i>=j)

    f[n][i][j]= i+j-1

    if(i<j)

    f[n][i][j]= 4n-i-j-1

    对于内圈:

    f[n][i][j]= f[n-2][i-1][j-1]+n*n-(n-2)*(n-2);

    初始状态:

    f[1][1][1]=1

    f[2][1][1]=1

    f[2][2][1]=2

    f[2][2][2]=3

    f[2][1][2]=4

    外圈表示:

    if(j==1||i==1||j==n||i==n)

    内圈表示:

    i>1&&i<n&&j>1&&j<n

    代码

     1 #include <iostream>
     2 using namespace std;
     3 int i=2,j=3,n=3;
     4 void luo(int n1)
     5 {
     6     int a=0,k,l;
     7     for (l=1;l<n1;l++)
     8     {
     9     a=a+n*4-l*8+4;
    10     }
    11     if (i>=j) printf ("%d",a+i+j-2*n1+1);
    12         else printf ("%d",a+(n-2*n1+1)*4-i-j+n1+n1+1);
    13 }
    14 int main()
    15 {
    16     freopen("in2.txt","r",stdin);
    17     int i1,j1;
    18     scanf ("%d %d %d",&n,&j,&i);
    19     //cout<<n<<j<<i;
    20     i1=i;
    21     j1=j;
    22     if (i1>n/2) i1=n-i1+1;
    23     if (j1>n/2) j1=n-j1+1;
    24     if(i1>j1) luo(j1);
    25         else luo(i1);
    26 }

     

  • 相关阅读:
    ASP.NET 页面间传递参数的方法
    Javascript 检查字符串是否是数字的几种方法
    周鸿祎教你写商业计划书
    提高网站程序性能的十条建议
    启动IIS6下Gzip功能详细操作步骤
    IT创业前要深思的八大问题
    学了php才知道MVC是怎么回事
    不能访问windows installer 服务 的解决方法
    SNS 相关
    【技术】Ubuntu上位机配置Blackfin开发环境手记
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7385514.html
Copyright © 2020-2023  润新知