目录
一.两个矩阵
1.回型矩阵
描述:给你一个整数n,按要求输出n∗n的回型矩阵。
输入描述:输入一行,包含一个整数n,1<=n<=19。
输出描述:输出n行,每行包含n个正整数。
例如:
输入:4
输出:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
这道题目,其实不难,观察我们可以发现
它是一圈一次循环,也就是说,我们只要写完一圈的代码,然后循环即可。不过还是要注意点细节。
#include<stdio.h>
int main()
{
int n,i,j;
int arr[20][20]={0};
scanf("%d",&n);
int out=1;
int x=0;
int y=n-1;
while(out<=n*n)
{
for(i=x;i<=y;i++)
arr[x][i]=out++;
for(i=x+1;i<=y;i++)
arr[i][y]=out++;
for(i=y-1;i>=x;i--)
arr[y][i]=out++;
for(i=y-1;i>x;i--)
arr[i][x]=out++;
x++;
y--;
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d ",arr[i][j]);
}
printf("\n");
}
return 0;
}
对于循环体内的代码端注意要把定量转换为变量。因为它是在不断变换之中的。
结果:
2.蛇形矩阵
描述:给你一个整数n,输出n∗n的蛇形矩阵。
输入描述:输入一行,包含一个整数n
输出描述:输出n行,每行包含n个正整数,通过空格分隔。1<=n<=1000
例如:
输入:
4
输出:
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
可以简单画个图分析一下:
①.暴力求解
通过这个图形,可以直观看到二维数组的变换,但是怎么转换成计算机语言还是比较难办的。笔者在初接触这个题目,是通过坐标直接暴力求解的,但是过于繁琐,也不易于调试,代码可读性较差。不过思路很明确。先见图:
上代码(笔者自己写的比较粗糙,但是万幸跑过去了)虽说比较暴力,但是还是由很多小细节需要注意的。
#include<stdio.h>
int main()
{
int n,i,j;
int arr[20][20]={0};
//找坐标关系
scanf("%d",&n);
int out=1;
int p=1;
//第一个没必要讨论
arr[0][0]=out++;
arr[n-1][n-1]=n*n;
while(p<n)//此处条件还可以写为p<=2*n-2
{
for(i=0;i<=p;i++)
{
arr[i][p-i]=out++;
}
p++;
if(p==n)
break;
for(i=p;i>=0;i--)
{
arr[i][p-i]=out++;
}
p++;
}
int x=1;
while(p<2*n-2)
{
if(n%2==0)
{
for(i=p-x;i>=x;i--)
{
arr[i][p-i]=out++;
}
p++;
x++;
if(p==2*n-2)
break;
for(i=x;i<=p-x;i++)
{
arr[i][p-i]=out++;
}
p++;
x++;
}
else
{
for(i=x;i<=p-x;i++)
{
arr[i][p-i]=out++;
}
p++;
x++;
if(p==2*n-2)
break;
for(i=p-x;i>=x;i--)
{
arr[i][p-i]=out++;
}
p++;
x++;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d ",arr[i][j]);
}
printf("\n");
}
return 0;
}
算是比较low了,写了有70多行。
②.优化算法(大神确实厉害👍)
如果不从坐标,换个角度思考呢?
为了方便我们从(1,1)开始初始化。
通过上述图片:
我们可以从,移动方向入手,分析发现,它的移动方向只有:
右和右上;
左和左下。
运动情况分为6种:
- 碰到上边界(即i等于1 且 j小于n): 列增加1,行不变--------往右移动一格
- 碰到左边界(即j等于1 且 i小于n): 行增加1,列不变--------往下移动一格
- 碰到右边界(即j等于n): 行增加1,列不变--------往下移动一格
- 碰到下边界(即i等于n): 列增加1,行不变--------往右移动一格
上面四种是在边界上行走的方式,下面就是在边界中间的运动情况。
- 除去上面四种的边界情况,就是在边界中间的左下移动
- 除去上面四种的边界情况,就是在边界中间的右上移动
#include <stdio.h> int array[1001][1001] = { 0 }; int main(void) { int n = 0; scanf("%d",&n); int i = 1, j = 1, k = 0,pos = 1; //pos代表方向移动 1代表右上 -1代表左下 array[i][j] = 1; for (k = 2; k <= n*n; k++) { if (i == 1 && j <n && pos ==1) //碰到上边界,列增加1,行不变 此后行增,列减 { array[i][++j] = k; pos = -1; //方向注意 } else if(j==1 && i<n && pos == -1)//碰到左边界,行增加1,列不变 此后行减,列增 { array[++i][j] = k; pos = 1; //方向注意 } else if (j == n && pos==1) //碰到左边界,行增加1,列不变 此后行增,列减 { array[++i][j] = k; pos = -1; //方向注意 } else if (i == n && pos ==-1) //碰到右边界,列增加1,行不变 此后行减,列增 { array[i][++j] = k; pos = 1; } else if (pos == 1) //除去上面的边界情况,就是中间移动过程 { array[--i][++j] = k; } else if(pos == -1) { array[++i][--j] = k; } } for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) printf("%d ",array[i][j]); printf("\n"); } return 0; }
不得不说,这段代码真的行云流水,大神厉害。
运行结果都是正确的。
二.两个圣诞树
1.普通圣诞树
描述
今天是圣诞节,牛牛要打印一个漂亮的圣诞树送给想象中的女朋友,请你帮助他实现梦想。
输入描述:输入圣诞树的高度h,1<= h <= 1001<=h<=100
输出描述:输出对应的圣诞树
示例1
输入:
1
输出:
*
* *
* * *
*
示例2
输入:
2
输出:
*
* *
* * *
* *
* * * *
* * * * * *
*
*
这道题目,比较需要注意的是空格,然后需要选取好对象,先抛去最后的小尾巴,前面我们就可以发现,它的基本最小组成单元:
*
* *
* * *
*
以此为基准进行扩张。(补充说明为什么要以此为基本单元,这一点比较细微,笔者也是观察试验了许久才发现,在笔者百思不得敲代码时发现每个小三角形的三行竟然都是一样的,连空格都一样,如果没有这个发现,这道题相当难做):
上代码:
#include<stdio.h>
int main()
{
//做三个特殊处理即可
int intm,num,i;
scanf("%d",&intm);
num=intm*3;
//如果进行3*intm次循环实在繁琐,所以进行intm次循环,但是要注意三行处理
for(i=1;i<=intm;i++)
{
//注意归并
for(int m=1;m<=num-1;m++)
{
printf(" ");
}
for(int n=1;n<=i;n++)
{
printf("* ");
}
printf("\n");
for(int m=1;m<=num-2;m++)
{
printf(" ");
}
for(int n=1;n<=i;n++)
{
printf("* * ");
}
printf("\n");
for(int m=1;m<=num-3;m++)
{
printf(" ");
}
for(int n=1;n<=i;n++)
{
printf("* * * ");
}
printf("\n");
num=num-3;
}
for(int k=1;k<=intm;k++)
{
for(int j=1;j<=(6*intm-1)/2;j++)
{
printf(" ");
}
printf("*\n");
}
return 0;
}
可爱的圣诞树🎄:
友友们不妨尝试一下送给自己的女朋友哦🌹。
2.超级圣诞树
描述
今天是圣诞节,牛牛要打印一个漂亮的圣诞树送给想象中的女朋友,请你帮助他实现梦想。
输入描述:输入圣诞树的大小 n n
1≤n≤81≤n≤8
输出描述:输出对应的圣诞树
输入:1
输入:2
输入:3
输入:4
这道题目笔者苦思冥想了两个小时也是没有头绪,只是发现每一个圣诞树都是以上一个圣诞树为基准,三个再重新为一个整体。也是求助了大神才得以解决。分享给大家,大神是真的厉害👍。其实也是我思维局限于上个普通圣诞树,一直想着通过打印或者坐标来解决,然而无果。大神的想法是建立一个二维数组,通过数字替换图形,然后循环。其中清空又重建的思维真的厉害。
上代码:
#include<stdio.h>
int main()
{
int arr[600][800]={{0,0,1,0,0},{0,1,0,1,0},{1,0,1,0,1}};//由0代表' ',1代表'*'
int n,i,j,k,length=3,width=5;
scanf("%d",&n);
//由小得到大
for(i=2;i<=n;i++)
{
//搬运
for(j=length;j<length*2;j++)
{
for(k=0;k<width;k++)
{
arr[j][k]=arr[j-length][k];//制作左下角三角形
arr[j][k+width+1]=arr[j][k];//制作右下角
}
}
//清空原来三角形,清空起初三角形是因为这个三角形不在中央,而在左边,为了放到中间而如此。
for(j=0;j<length;j++)
{
for(k=0;k<width;k++)
{
arr[j][k]=0;//清空
}
}
//把三角形放到中央
for(j=0;j<length;j++)
{
for(k=(width+1)/2;k<width+(width+1)/2;k++)
{
arr[j][k]=arr[j+length][k-(width+1)/2];
}
}
//变化的数组,需要扩大,以变大后的三角形为新的初始三角形进行变化。当真绝妙。
length*=2;width=width*2+1;
}
for (i = 0; i < length; i++)
{//打印圣诞树
for (j = 0; j < width; j++)
{
if (arr[i][j] == 0)
{
printf(" ");
}
else
{
printf("*");
}
}
printf("\n");
}
for (i = 0; i < n; i++)
{//打印树干
for (j = 0; j < width / 2; j++)
{
printf(" ");
}
printf("*\n");
}
return 0;
}
友友们也可以实现送给自己的女朋友哦🌹。这些题目都是牛客网上初阶的题目,较为简单,大家可以点题目就有链接哦。
本次分享就到这里,谢谢大家!🌹