最近在Codevs上面做了道题,个人感觉这题在入门级别的模拟是比较有代表性的。

这是小弟第一次写解题报告,而且编程水平有待提高,故代码可能有些乱。大神看到了有什么地方有错误或者有什么要改进的地方,欢迎指出。
好了,下面进入正题。这题在Codevs的题号是1160,题目名字叫蛇形矩阵。但是我在网上搜索了一下发现,真正的蛇形矩阵应该是Problem 1083………这个就不管那么多了。

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

这题一看还挺有意思的。就是数字在矩阵中心绕着扩大。。如果是在纸上写的话,相信每个人都会。但是关键问题是……这个问题是要编成程序的。规律在哪呢?

在一开始的时候,向右增加1位,第二次向上增加1位,第三次向左增加2位,第四次向下增加2位,第五次又向右增加三位……基本规律也就明白了

下面上程序:

#include
int main()
{
int tot=1,n,x,y,l=0,a[109][109];
//将整个二维数组置0
for(int i=0;i<1
00;i++){

for(int j=0;j<100;j++)
a[i][j]=0;
}
scanf("%d",&n);
//整个矩阵的中心(也就是起点)=1
a[(n-1)/2][(n-1)/2]=1;
//等会操作使用的x,y指向矩阵中心
x=(n-1)/2; y=(n-1)/2;
//模拟开始
while(tot<=n*n) //当计数器小于边的平方时循环
{
int x1=x,y1=y; l++; //l就是本次需要加的边数
for(int i=x1;i<x1+l;i++){
x++; tot++; a[x][y]=tot;
}
x1=x;y1=y;//因为x,y时刻在变化,所以先设定一个变量存储本次行走的起点
for(int i=y1;i<y1+l;i++){ y++; tot++; a[x][y]=tot; } l++;//两边过后步长加大1 x1=x;y1=y; for(int i=x1;i>x1-l;i--){
x--; tot++; a[x][y]=tot;
}
x1=x;y1=y;
for(int i=y1;i>y1-l;i--){
y--; tot++; a[x][y]=tot;
}
}
int djx=0; //对角线之和
//打以下代码时思维比较混乱QAQ,所以代码比较乱。
for(int j=n-1;j>=0;j--){
for(int i=0;i<n;i++){
printf("%d ",a[i][j]);
if(j==i) djx+=a[i][j]; //对角线判断
}
printf("\n");}
//又写了一个模拟。。不知道当时怎么想的。。
int f=0,e=n;
for(f;f<=n;f++){
e--;
djx+=a[f][e];
}
//因为矩阵中心元素算了两遍,所以减去一个
printf("%d",djx-a[(n-1)/2][(n-1)/2]);
return 0;
}

内容都在代码里有注释讲解,就不详细介绍了……个人感觉这个代码比较糙。欢迎大神前来吐槽……
好了这份解题报告到这里也就差不多了吧……下面说一下我和lyx关于OI学习解题报告的约定:

  • 近期每人完成一份基础题的解题报告
  • 3,4,5月每人每月完成一份解题报告,内容以算法基础为主
  • 暑假另做安排

*6月因为我们都要中考了,so……
好了这次的解题报告#1:某科学的矩阵就在这结束啦~各位大神可以在评论区随意吐槽