大蒟蒻LJ解题报告#1:某科学的矩阵

发布于 2016-02-15  2676 次阅读


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

这是小弟第一次写解题报告,而且编程水平有待提高,故代码可能有些乱。大神看到了有什么地方有错误或者有什么要改进的地方,欢迎指出。

好了,下面进入正题。这题在Codevs的题号是1160,题目名字叫蛇形矩阵。但是我在网上搜索了一下发现,真正的蛇形矩阵应该是Problem 1083………这个就不管那么多了。

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

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

经过一段时间的分析以后……我画了一张图:

SF1

在一开始的时候,向右增加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:某科学的矩阵就在这结束啦~各位大神可以在评论区随意吐槽01f34933c8c8df18486bf1cbbe2a6684_b

-EOF-


等风来,不如追风去。