本题目为东北师范大学信息科学与技术学院2019年硕士研究生媒体技术科目招生试题,由一位高中同学提供,让我三年没用C的又重操旧业。
题目内容:编写程序按下面指定的数据为数组x的下三角元素赋值,并按如下形式输出:
4
3 7
2 6 9
1 5 8 10
方法一:找规律大法
俗话说,找到规律最简单,轻轻松松一个通式就解决。
首先观察每列,从上到下逐次减1,用宏定义level表示这个数组有几行,用i、j分别表示第i行和第j列(这里i和j从0开始)。则第i行第0列的元素可以表达为level-i。
从第1列开始整列可以看作是第0列都增加某个值,第1列相比第0列增加4(level),第2列相比第0列增加4+3=7(level+level-1=2*level-1),第3列相比第0列增加4+3+2=9(level+level-1+level-2=3*level-3)……
则第j列相比第0列增加的项的第一项为j*level,第二项为0,1,2,3,....j-1之和,由通项公式得,第二项为j(j-1)/2,所以总增加为j*level+j(j-1)/2.
综上所述,表达式可以写为num[i][j]=level-i+level*j-j*(j-1)/2;
方法二:循环法
循环法就灰常简单了,每一列都是从最底下那个元素开始向上递增,并且每一列的最下一个元素都比上一列的最上一个元素大一,即所有的元素都是按列从下到上连续的。
那就好整了,假设数组一共level行,下三角数组一共有level*(level+1)/2个,那我先初始变量index为0,用来表示每次赋值的赋值数,初始化pi为level-1,初始化pj为0,即表示当前第level-1行第j列。
然后进入while循环,循环条件为index小于level*(level+1)/2,如果大于则跳出。
在循环中,首先把num[pi][pj]赋值为index+1(因为从1开始),然后index自增,进行如下判断:如果pi==pj,即当前元素在主对角线上,也就意味着到了下三角数组该列的最顶上,则需要pi重新初始化为level-1,pj自增,否则pi自减。
代码:
方法一:
#include <stdio.h>
#define level 4
int main(){
int num[level+1][level+1];
for(int i=0;i<level;i++){
for(int j=0;j<level;j++){
if (i>=j){//下三角
num[i][j]=level-i+level*j-j*(j-1)/2;
printf("%d",num[i][j]);
if(i!=j){
printf(" ");
}
}
}
printf("\n");
}
}
方法二:
#include <stdio.h>
#define level 4
int main(){
int num[level+1][level+1];
int number=level*(level+1)/2;
int index=0;
int pi=level-1;//假装我是指向行数的指针
int pj=0;//假装我是指向指向列数的指针
while(index<number){
num[pi][pj]=index+1;//日常赋值
index++;
if(pi==pj){//如果到主对角线 则跳转到下一列的末尾
pi=level-1;
pj++;
}
else{//否则跳转到上一行
pi--;
}
}
for(int i=0;i<level;i++){
for(int j=0;j<level;j++){
if (i>=j){//下三角
printf("%d",num[i][j]);
if(i!=j){
printf(" ");
}
}
}
printf("\n");
}
}