• CODE[VS]-蛇形矩阵-模拟-天梯白银


    题目描述 Description

    小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该n行n列正方形矩阵以及其的对角线数字之和.

    输入描述 Input Description

    n(即n行n列)

    输出描述 Output Description

    n+1行,n行为组成的矩阵,最后一行为对角线数字之和

    样例输入 Sample Input

    3

    样例输出 Sample Output

    5 4 3
    6 1 2
    7 8 9
    25

    数据范围及提示 Data Size & Hint

    思路:对于这题,刚开始我是想用数学公式来表示每一个点的计算方法,但是经过复杂的计算后,我放弃了,点太多而且很难表达,所以我就纯粹地模拟了一下

    光讲思路没有用,还是要举个栗子(7*7的矩阵):

    我用了四个for循环,从外往内标记数组,分别为下、左、上、右,这样经过一轮下来就是一个框了,外面再用一个循环来控制框的数量,就可以完整地把矩阵标记完全

    所以这题关键就是要考虑的就是四个for循环的气质条件和循环次数,为了方便,我用了一个flag记录框的层数,最外层是第一层(flag=1),temp来控制框的数量(循环的数量):temp=(n-1)/2

    如图所示,我先对这个矩阵做了一些处理,也就是把每一个框的起点先标记好:

    如图所示,红色的线标记出来了下左上右的循环起止点,这样就可以嵌套成为一个完整的框了:

    那么该怎样确定循环的起止点呢?这里就要用到前面的flag层数了,仔细观察可以发现:

    第一个for循环j的起点=n-flag-1,终止点为flag-1;

    第二个for循环i的起点=n-flag-1,终止点为flag-1;

    第三个for循环j的起点=flag,终止点为n-flag;

    第四个for循环的起点=flag,终止点为n-flag-1。

    每次a[i][j]都赋值为前面的数+1即可,用一个temp来控制框的数量,每次temp--就可以啦

    最后计算对角线的和,这里没什么好说的了,记得最后要减去一个重复的1

    代码如下:

     1 #include <stdio.h>
     2 int main()
     3 {
     4     int n,i,j;//i表示行,j表示列 
     5     int a[101][101]={0};
     6     int kk=1;//用来计算奇数的平方 
     7     int flag=1,temp;//flag记录循环的层数,temp控制循环终止条件 
     8     int ans=0;//记录两条对角线的和    
     9     scanf("%d",&n);
    10     temp=(n-1)/2;
    11     a[(n-1)/2][(n-1)/2]=1;//最中间标记为1    
    12     for(i=(n-1)/2;i<n;i++)//放入循环开始点 
    13     {
    14         a[i][i]=kk*kk;
    15         kk+=2;
    16     }
    17     while(temp>0)//循环填入边框 
    18     {
    19         for(j=n-flag-1;j>=flag-1;j--)//
    20         {
    21             a[n-flag][j]=a[n-flag][j+1]-1;
    22         }    
    23         for(i=n-flag-1;i>=flag-1;i--)//
    24         {
    25             a[i][flag-1]=a[i+1][flag-1]-1;
    26         }    
    27         for(j=flag;j<=n-flag;j++)//
    28         {
    29             a[flag-1][j]=a[flag-1][j-1]-1;
    30         }
    31         for(i=flag;i<=n-flag-1;i++)//
    32         {
    33             a[i][n-flag]=a[i-1][n-flag]-1;
    34         } 
    35         flag++;//进入下一层 
    36         temp--;//循环次数减少 
    37     }    
    38     for(i=0;i<n;i++)//输出矩阵 
    39     {
    40         for(j=0;j<n;j++)
    41         {
    42             printf("%d ",a[i][j]);
    43         }
    44         printf("
    ");
    45     }
    46     /*====================*///计算两条对角线的和 
    47     for(i=0;i<n;i++)
    48     {
    49         ans+=a[i][i];
    50     }
    51     for(i=n-1;i>=0;i--)
    52     {
    53         ans+=a[n-1-i][i];
    54     }
    55     printf("%d
    ",ans-1);//因为两条对角线都重复加了矩阵中心的1,所以要减去一个 
    56     return 0;
    57 }
  • 相关阅读:
    如何在Ubuntu下通过USB连接iPone/iPod
    全手动封装教程+SRS9.80102 文本教程(适合初学)
    PHP 面试踩过的坑
    视频 | 一步步教你操作websocket通知案例
    在职场,辞退你、培养你,从来不是看能力
    git撤销本地修改与回退版本
    异步发送邮件完整示例
    如何解决Redis缓存和MySQL数据一致性的问题?
    PHP 面试踩过的坑(二)
    守护进程、信号和平滑重启
  • 原文地址:https://www.cnblogs.com/geek-007/p/5675973.html
Copyright © 2020-2023  润新知