星球杯实验室2022.10.20作业题解

A:题目 1030: 

[编程入门]二维数组的转置

#include <stdio.h>
int main(){
    int a[3][3];
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            scanf("%d",&a[i][j]);
        }
    }
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            printf("%d ",a[j][i]);
        }
        printf("\n");
    }
} 

行列互换,那么我们就按行输入,按列输出即可转置,同时输出时不要忘了每三个数字换行。


B:题目 1138: 

C语言训练-求矩阵的两对角线上的元素之和

#include <stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    int a[n][n];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            scanf("%d",&a[i][j]);
        }
    }
    int l=0,r=n-1;
    int sum=0;
    for(int i=0;i<n;i++){
        if(l!=r) sum+=a[i][l]+a[i][r];
        else sum+=a[i][l];
        l++;
        r--;
    }
    printf("%d",sum);
}

首先我们建立一个二维数组,然后我们再建立两个坐标变量,l和r,分别每一轮循环结束后,l++,r--,这样a[i][l]和a[i][r]始终都会是对角线上的元素,但注意,当n是奇数的时候,中间的数会被重复加一遍,所以我们多进行一轮判定,当l==r时,只加一遍。


C:题目 1164: 

数组的距离

#include <stdio.h>
#include <math.h>
int main(){
    int m,n;
    scanf("%d %d",&m,&n);
    int f[m],g[n];
    for(int i=0;i<m;i++){
        scanf("%d",&f[i]);
    }
    for(int i=0;i<n;i++){
        scanf("%d",&g[i]);
    }
    int ans=1e9;//科学计数法,表示1*10^9
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            ans=ans<abs(f[i]-g[j])?ans:abs(f[i]-g[j]);
        }
    }
    printf("%d",ans);
}

先定义两个数组并输入,然后开一个for循环,依次比较即可,这里用到了math.h头文件求绝对值。本题可以优化掉一个循环与一个数组,即不建立第二个数组,而是定义一个变量,每输入一次便循环进行比较,代码如下

#include <stdio.h>
#include <math.h>
int main(){
    int m,n;
    scanf("%d %d",&m,&n);
    int f[m],g;
    for(int i=0;i<m;i++){
        scanf("%d",&f[i]);
    }
    int ans=1e9;//科学计数法,表示1*10^9
    for(int j=0;j<n;j++){
        scanf("%d",&g);
        for(int i=0;i<m;i++){   
            ans=ans<abs(f[i]-g)?ans:abs(f[i]-g);
        }
    }
    printf("%d",ans);
}

D:题目 1860: 

区间中最大的数

#include <stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    int a[n+1];
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int q;
    scanf("%d",&q);
    while(q--){
        int i,j;
        scanf("%d %d",&i,&j);
        int max=0;
        for(i;i<=j;i++){
            max=a[i]>=max?a[i]:max;
        }
        printf("%d\n",max);
    }
}

只需建立一个数组并循环比较q次即可


E:题目 2834: 

与指定数字相同的数的个数

#include <stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    int a[n];
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    int m;
    scanf("%d",&m);
    int ans=0;
    for(int i=0;i<n;i++){
        if(a[i]==m) ans++;
    }
    printf("%d",ans);
}

简单的循环比较即可做出,没什么好说的


F:题目 2837: 

年龄与疾病

#include <stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    int a[n];
    float stage1=0.0,stage2=0.0,stage3=0.0,stage4=0.0;
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        if(a[i]<=18) stage1++;
        else if(a[i]<=35) stage2++;
        else if(a[i]<=60) stage3++;
        else stage4++;
    }
    float rate1,rate2,rate3,rate4;
    rate1=stage1/n*100;
    rate2=stage2/n*100;
    rate3=stage3/n*100;
    rate4=stage4/n*100;
    printf("%.2f%%\n%.2f%%\n%.2f%%\n%.2f%%",rate1,rate2,rate3,rate4);
}

这题唯一需要注意的就是百分数该如何表达,以及输出%需要用到转义字符%%,其他没什么难的地方了。


G:题目 2896: 

二维数组右上左下遍历

#include <stdio.h>
int main(){
    int row,col;
    scanf("%d %d",&row,&col);
    int a[row][col];
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++){
            scanf("%d",&a[i][j]);
        }
    }
    int i=0,j=0;
    for(i=0;i<row;i++){
        if(j!=col-1){//判断j是否增大至数组边界,没有达到边界则j的初值依次增加
        for(j=0;j<col;j++){//j的初值从0开始增加
            int temp1=i,temp2=j;
            for(temp1,temp2;temp1<row&&temp2>=0;temp1++,temp2--){//i++,j--即向左下移动
                printf("%d\n",a[temp1][temp2]);//输出
            }
            if(j==col-1) break;//如果不加break的话,j最后还会再加一遍,导致越界
        }
        }
        else{//如果j增大至边界值则j的初值不变
            int temp1=i,temp2=j;
            for(temp1,temp2;temp1<row&&temp2>=0;temp1++,temp2--){
                printf("%d\n",a[temp1][temp2]);
            }
        }
        //程序可以运行到这里证明此时j的值已经增大至数组边界
        //此时i的初值开始增加
    }
}

其实没什么难的,简单的数组和循环的应用(我的解法肯定不是最优解),但比较绕,需要多加思索。

 根据每次输出的数字所在数组位置,我们关注j可以发现规律并分组(上图红线),可以发现,前四组的i的初值都是0但j的初值在逐渐变大,并在j的初值达到最大值3(数组边界),此时i的初值开始逐渐变大而j的初值则维持在最大值保持不变。而且每组循环内i和j都是同步变化,也就是i++的同时j--,并在i和j其中一个值达到边界时(i==2||j==0)结束本组循环。根据这个规律,我们可以写出循环,结合代码与注释观看题解体验更佳。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值