嗯……最近在Codevs上面做了道题,个人感觉这题在入门级别的模拟是比较有代表性的。
这是小弟第一次写解题报告,而且编程水平有待提高,故代码可能有些乱。大神看到了有什么地方有错误或者有什么要改进的地方,欢迎指出。
好了,下面进入正题。这题在Codevs的题号是1160,题目名字叫蛇形矩阵。但是我在网上搜索了一下发现,真正的蛇形矩阵应该是Problem 1083………这个就不管那么多了。
题目是这样的:小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该n行n列正方形矩阵以及其的对角线数字之和。
这题一看还挺有意思的。就是数字在矩阵中心绕着扩大。。如果是在纸上写的话,相信每个人都会。但是关键问题是……这个问题是要编成程序的。规律在哪呢?
经过一段时间的分析以后……我画了一张图:
在一开始的时候,向右增加1位,第二次向上增加1位,第三次向左增加2位,第四次向下增加2位,第五次又向右增加三位……基本规律也就明白了
下面上程序:
#include<cstdio> int main() { int tot=1,n,x,y,l=0,a[109][109]; //将整个二维数组置0 for(int i=0;i<100;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……
好了这次大蒟蒻LJ的解题报告#1:某科学的矩阵就在这结束啦~各位大神可以在评论区随意吐槽
-EOF-
Comments | 8 条评论
博主 linjing_10
沙发自占~
博主 danihao123
@linjing_10 你可以试着去做做POI2008的SZK这道思考题(当然只输出发射接收的对数就行了)
博主 danihao123
从前,NOIP(2014年)考过一道类似的题(但是从外到里,要难很多)。当时那题白送50分(暴力分)没拿到,因为我输出了个指针= =
博主 linjing_10
@danihao123 你说的是…类似紫书40页的那个?个人感觉那题比这个简单很多。。因为有边界。。话说滥用指针害人不浅啊23333
博主 danihao123
@linjing_10 如果是NOIP2014那题的话,直接开数组有爆内存的风险,然而我太弱了没办法233
博主 Menci
@danihao123 NOIP2014?!哪道?
博主 danihao123
@Menci PJT3
博主 Menci
@danihao123 qwq PJ的题没刷过w