NOIP201403螺旋矩阵

NOIP201403螺旋矩阵

  • 题目
    • 链接
    • 字面描述
      • 题目背景
      • 题目描述
      • 输入格式
      • 输出格式
      • 样例 #1
        • 样例输入 #1
        • 样例输出 #1
      • 提示
  • 思路
  • 代码实现
    • O(n)
    • O(1)

题目

链接

https://www.luogu.com.cn/problem/P2239

字面描述

题目背景

NOIP2014 普及组 T3

题目描述

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

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

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

 1     2     3     4
12    13    14     5
11    16    15     6
10     9     8     7

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

输入格式

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

输出格式

一个整数,表示相应矩阵中第 i i i 行第 j j j 列的数。

样例 #1

样例输入 #1

4 2 3

样例输出 #1

14

提示

【数据说明】

对于 50 % 50\% 50% 的数据, 1 ⩽ n ⩽ 100 1 \leqslant n \leqslant 100 1n100;

对于 100 % 100\% 100% 的数据, 1 ⩽ n ⩽ 30 , 000 , 1 ⩽ i ⩽ n , 1 ⩽ j ⩽ n 1 \leqslant n \leqslant 30,000,1 \leqslant i \leqslant n,1 \leqslant j \leqslant n 1n30,000,1in,1jn

思路

我们可以用递归去解决这题,把每层看成2列2行去解决
若一个表格nn
若解在第一行 答案为j
若解在第n列答案为n+i-1
若解在第n行答案为3
n-2-j+1
若解在第1列答案为4*n-4-i+2

代码实现

O(n)

#include
using namespace std;

int n,i,j;
inline int work(int n, int i, int j) {
    if (i==1)return j;
    if(j==n)return n+i-1;
    if(i==n)return 3*n-2-j+1;
    if(j==1)return 4*n-4-i+2;
    return work(n-2,i-1,j-1)+4*(n-1);
}
int main(){
	scanf("%d%d%d",&n,&i,&j);
	printf("%d\n",work(n,i,j));
	return 0;
}

O(1)

#include 
#define ll long long
using namespace std;
int main() 
{
    ll n,i,j,minn,ans=0;
    cin>>n>>i>>j;
    minn=min(i,min(j,min(n-i+1,n-j+1)));
    int k=4*minn;
    if(i<=j)  ans=minn*(4*(n-1)-k)+10*minn-4*n-3+i+j;
    else ans=minn*(4*n-k)+2*minn+1-i-j;
    cout<<ans;
    return 0;
}

你可能感兴趣的:(题解)