p2239 螺旋矩阵

z

你没有发现两个字里的blog都不一样嘛 qwq

题目描述--->p2239 螺旋矩阵

看到题,很明显,如果直接模拟的话,复杂度为\(O(n^2)\)过不去.(这个复杂度应该不正确,我不会分析的啊 qwq.

因此我们需要一个比较厉害的方法解决这个题,

前置知识

我们手写一些矩阵,发现我们填的数是会分层的 !.

(同种颜色为一层.)

分层这个东西的话,我也不能具体解释,你可以认为是一圈一圈地填数.

xjb分析

打表!找规律

我们可以手写一个程序,(也可以手写,手写的话会更简单一些.)

模拟一下这个过程.

例如这个程序(话说,打个表我想了半小时? qwq 一定是我太垃圾了

下面的变量\(ceng\)的话,是因为构造出来的矩阵会分层。

void get(int n)
{
    int cnt=0,x=1,y=1;
    for(R int ceng=1;ceng<=(n+1)/2;ceng++)
    {
        while(y<=n-ceng+1)
            res[x][y++]=++cnt;x++;y--;
        while(x<=n-ceng+1)
            res[x++][y]=++cnt;x--;y--;
        while(y>=ceng)
            res[x][y--]=++cnt;y++;x--;
        while(x>ceng)
            res[x--][y]=++cnt;x++;y++;
    }
    print();
}

打出来5*5的表是这样的 qwq

开始搬砖找规律.

  1. 第\(1\)行第\(j\)列对应的数就是j
  2. 第n列第\(i\)行对应的为\(n+x-1\)
  3. 第n行第\(j\)列对应的数为$3 \times n-j-1 $
  4. 再度填回第\(1\)列,第\(i\)行我们发现得到的对应数为 \(4 \times n-i-2\)

上面四点是最容易发现的规律,也是我们继续求解的关键.

注意: 如果上面四条规律并没有找到的话,希望大家能自己手推找一下规律.

(PS: 本人开始用6*6的表格找规律,结果第四条规律找错 qwq)

如何填充里层的数?

我们发现17这个位置与16是有关的.而16,又是\(4\times5-4\)

(多打几个表容易发现,第\(2\)行第\(1\)列这个位置的数为\(4 \times n-4\))

然后考虑搞事。

我们将更里层的数减去\(4\times n-4\),得到新的里层数据如下.

这时候你可能会大吼.

“woc!又让我填一遍?”

恍然大悟

我们发现,这样的话,我们又填一次这个矩阵,不过这个矩阵的大小从\(n\)变成了\(n-2\)

(消去了,最左和最右两边.)

而假设我们之前要查找的数的位置为\((4,4)\)就变成了\((3,3)\)

如果是\((3,4)\)就变成了\((2,3)\),

所以说,当我们求内层的时候,所求原数的位置(x,y)就将变成(x-1,y-1).

而对于那些直接满足上面我们发现的规律的数的话,我们可以直接输出.

所以不必考虑这些数的输出怎么办.

最终我们一定会拆到最里层.

以此类推

我们一直拆下去,每次加上的答案就是\(4\times n-4\)。

注意:这个n是在变化的.

因此我们可以码出代码

#include<bits/stdc++.h>
#define R register
using namespace std;
inline void in(int &x)
{
    int f=1;x=0;char s=getchar();
    while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    x*=f;
}
int n,x,y,ans;
int main()
{
    in(n),in(x),in(y);
    //如果刚开始的话x,y就满足四条规律.
    //我们会在第一次输出答案,此时ans为0,无影响.
    here:;
    if(x==1)printf("%d",y+ans);
    else if(y==n)printf("%d",n+x-1+ans);
    else if(x==n)printf("%d",3*n-y-1+ans);
    else if(y==1)printf("%d",4*n-x-2+ans);
    else
    {
        ans+=4*n-4;
        x--,y--,n-=2;
        goto here;
        //这句话达到了递归的效果。
        //我们的程序运行到这一步会到达上面的here,即再度执行这些if语句.
    }
}

原文地址:https://www.cnblogs.com/-guz/p/9703556.html

时间: 2024-10-01 23:59:47

p2239 螺旋矩阵的相关文章

P2239螺旋矩阵

传送 看到这数据范围,显然咱不能暴力直接模拟(二维数组开不下,而且会T掉) 我们目前有两种选择: 1.优化暴力  走这边(jyy tql%%%) 2.数学做法 我们看一下题目中的那个矩阵 我们能不能找到些什么规律 由肉眼观察得 (1,1)=1 (n,n)=2*n-1 (1,n)=3*n-2 (2,1)=4*n-4 好像似乎有那么点规律 所以我们不妨把当前的矩阵分成4部分 i=1,ans=j j=n,ans=2*n-1-(n-i)=n-1+i(这里可以理解为从(n,n)向上的(n-i)行的数) i

2014螺旋矩阵

题目描述 Description 一个 n 行 n 列的螺旋矩阵可由如下方法生成: 从矩阵的左上角(第 1 行第 1 列)出发,初始时向右移动:如果前方是未曾经过的格子, 则继续前进,否则右转:重复上述操作直至经过矩阵中所有格子.根据经过顺序,在格子中 依次填入 1, 2, 3, ... , n2,便构成了一个螺旋矩阵. 下图是一个 n = 4 时的螺旋矩阵. 1  2  3  4 12  13  14  5 11  16  15  6 10  9  8  7 现给出矩阵大小 n 以及 i 和

每日算法之四十一:Spiral Matrix II (螺旋矩阵)

Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For example, Given n = 3, You should return the following matrix: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 针对这个问题采用最直观的方式即可,即螺旋插入,这里有两个地方需要注意,一个是插入边界的界定,

1050. 螺旋矩阵(25)

本题要求将给定的N个正整数按非递增的顺序,填入“螺旋矩阵”.所谓“螺旋矩阵”,是指从左上角第1个格子开始,按顺时针螺旋方向填充.要求矩阵的规模为m行n列,满足条件:m*n等于N:m>=n:且m-n取所有可能值中的最小值. 输入格式: 输入在第1行中给出一个正整数N,第2行给出N个待填充的正整数.所有数字不超过104,相邻数字以空格分隔. 输出格式: 输出螺旋矩阵.每行n个数字,共m行.相邻数字以1个空格分隔,行末不得有多余空格. 输入样例: 12 37 76 20 98 76 42 53 95

leetcode-Spiral Matrix II 螺旋矩阵2之python大法好,四行就搞定,你敢信?

Spiral Matrix II 螺旋矩阵 Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For example,Given n = 3, You should return the following matrix: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 真的不容易..看博客园有人面试碰到过这个问题,长篇

Java-基础编程(螺旋矩阵&amp;乘法表)

package cn.rick.study; import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.Scanner; /** * * @author Rick-bao date 2014-8-29 * */public class SomeBasicCode { public static void main(String[] args) { MultiplicationTable();//

HLG 1564 螺旋矩阵 (趣味C语言)

链接: http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1564 Description 对于给定的一个数n,要你打印n*n的螺旋矩阵. 比如n=3时,输出: 1 2 3 8 9 4 7 6 5 Input 多组测试数据,每个测试数据包含一个整数n(1<=n<=32) Output 对于每组测试数据,输出一个n*n的螺旋矩阵,定义在题目描述里. 在一组测试数据中,每个数占的字符宽度

从外向内扩的螺旋矩阵

形如: 1   2   3   4  5 16 17 18 19  6 15 24 25 20  7 14 23 22 21  8 13 12 11 10  9 如果我们需要打印这样从外部向内扩展的n * n矩阵. 分析: 可以把矩阵分为n/2个圈, (上面的例子分了两个圈,最外面的圈就是12345~16,另外一个圈就是17~24) 我们只需要以圈为单位,给二维数组中的每个数赋值.赋值的顺序也是按照数字的递增顺序(顺时针) Java代码如下: public class SpiralMatrix

编程题之打印二维螺旋矩阵

当size=4时, 二维螺旋矩阵如下图所示: 规律总结 可以把这个二维矩阵看成一层套一层,如上图所示,1->4->7->10->12为第零层, 13->14->15->16为第一层,所以当size=4时,总共有两层.规律如下: 可分层数为:若size为偶数,层数=size/2, 若为奇数,则层数=(size+1)/2; 第n层一个方向上的数字的数量为:size-2*n; 这是因为第零层的一个方向上数字的数量就是size, 而第一层是size-2,...第n层就是s