题目73:稀疏矩阵


今天明明学到了什么叫做矩阵,但他发现要将一个矩阵输入进电脑是一件很麻烦的事。特别是有些矩阵很大,且大部分元素都是0,我们称这类 矩阵为稀疏矩阵。 于是,明明发明了一种简单的表示方法,只指出矩阵中非零元素来表示该矩阵。

例如一个矩阵:

0 0 0 5

2 0 0 0

0 1 0 0

0 0 4 0

可以表示成:

1 4 5

2 1 2

3 2 1

4 3 4

但明明又开始力不从心了,于是再一次想到了你...

明明的问题可以归结为:试编程将一个稀疏矩阵a转换成只存放非零元素的矩阵b,即找出每个不是0的元素,按从左到右从上到下的顺序,输出其所在的行和列以及它的值。

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。每组数据的第一行包括两个整数,M和N,用空格隔开,表示矩阵大小为M * N(1 ≤ M, N ≤ 20),之后的M行每行有N个整数,也用空格隔开,整数的大小不会超出int型,且必有一个数非零。行首行尾没有空格,每组测试数据之间也没有多余空行。

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。对应每组输入数据,用明明的矩阵表示法输出该矩阵,即找出每个不是0的元素,按从左到右从上到下的顺序,输出其所在的行和列(行、列下标从1开始)以及它的值。其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间有一个空行,最后一组运算结果后面没有空行。 注:通常,显示屏为标准输出设备。

总结:

将输入的系数矩阵存入二维数组 arr[m][n] 中,遍历稀疏矩阵,若该某位置上值不为0,输出该数据的行数和列数(数组下标+1)以及该数据

#include <stdio.h>
int main(){
    int m, n;
    while(scanf("%d %d", &m, &n) != EOF){
        int arr[m][n];
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++)
                scanf("%d", &arr[i][j]);
        }
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(arr[i][j] != 0)
                    printf("%d %d %d\n", i + 1, j + 1, arr[i][j]);
            }
        }
        printf("\n");
    }
    return 0;
}
 

题目74:矩阵转换


明明是一个很聪明的孩子,学什么东西都很快。但是他也有个缺点,就是不愿意做重复的 劳动,往往学会一样东西以后,就不太愿意再去碰它。有一天,明明在数学课上学了矩阵的转换,即有一个r×r的矩阵,把矩阵中的数以左上到右下的对角线的方式进行交换,然后形成一个新的矩阵。

例如:有个3×3的矩阵如下:

1 2 3

4 5 6

7 8 9

通过以左上到右下的对角线交换后,形成了一个新的矩阵:

1 4 7

2 5 8

3 6 9

明明很快就学会了,然后自己动手做了几个类似的转换。但是,课后老师布置了很多矩阵转换的作业,让同学回家练习,这就使明明很厌烦了,觉得自己已经学会了,就没有再练习的必要了。于是明明就请你帮个忙,帮他写一个程序,来计算矩阵的交换,帮他完成老师布置的作业。

明明的问题可以归结为:有一个r×r的矩阵,把矩阵中的数以左上到右下的对角线的方式进行转换,然后输出转换后的矩阵。

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据有多行,每组测试数据的第一行有一个整数r(1≤r≤10),表示一个r×r的矩阵,接下来有r行,每行有r个整数,表示要转换的矩阵中的数,每个数用一个空格隔开。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个转换后的矩阵。每组运算结果形成r行数据,每一行的数字之间以一个空格分隔,其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间有一个空行,最后一组运算结果后面没有空行。 注:通常,显示屏为标准输出设备。

总结:

1. 将输入的数据存入二维数组 arr[n][n],创建新数组 b[n][n],存储转置后的数组

2. 遍历 arr 数组,将 arr 数组每行的数据存入 b 数组的列中

#include <stdio.h>
int main(){
    int n;
    while(scanf("%d", &n) != EOF){
        int arr[n][n], b[n][n];
        for(int i = 0; i < n; i++){
            for(int j = 0;j < n; j++)
                scanf("%d", &arr[i][j]);
        }
        for(int i = 0; i < n; i++){
            for(int j = 0;j < n; j++){
                b[j][i] = arr[i][j];
            }
        }
        for(int i = 0; i < n; i++){
            for(int j = 0;j < n; j++){
                printf("%d", b[i][j]);
                if(j < n - 1)
                    printf(" ");
                else
                    printf("\n");
            }
        }
        printf("\n");
    }
    return 0;
}
 

题目75:魔方阵


在一次数学课上,明明的老师讲了一种非常有趣的方阵,称之为三阶魔方阵。

它是一个三行三列,由1、2、3、……8、9,九个数字共同构成,且它每行、每列、两对角线之和均相等,于是一个合法的三阶魔方阵就形成了以下的方阵:

8 1 6

3 5 7

4 9 2

富有钻研精神的明明回家后,马上就对三阶魔方阵进行研究。

他总结出了5条n阶魔方阵的规律(n为奇数),如下:

(1) 将“1”放在第一行(最上面一行)中间一列;

(2) 从“2”开始直到n*n为止各数依次按下列规则存放:每一个数存放的行的行数比前一个数的行数减1,每一个数存放的列的列数比前一个数的列数加1,即前一个数的右上方。

(3) 如果上一数的行数为1,则下一个数的行数为n(指最下面一行);

(4) 当上一个数的列数为n时,下一个数的列数应为1(指最左一列);

(5) 如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面。

有了以上的方法,明明就可以轻易地构造出任意的n阶魔方阵。

例如构造3阶魔方阵的过程如下:

先将1放在第一行的中间一列:

放1:(参考规则1)

* 1 *

* * *

* * *

放2:(参考规则3)

* 1 *

* * *

* * 2

放3:(参考规则4)

* 1 *

3 * *

* * 2

放4:(参考规则5)

* 1 *

3 * *

4 * 2

放5:(参考规则2)

* 1 *

3 5 *

4 * 2

放6:(参考规则2)

* 1 6

3 5 *

4 * 2

放7:(参考规则5)

* 1 6

3 5 7

4 * 2

放8:(参考规则4)

8 1 6

3 5 7

4 * 2

放9:(参考规则3)

8 1 6

3 5 7

4 9 2

但是随着n的不断增大,构建一个n阶魔方阵所花的精力就越多。于是明明就请你帮忙,帮助他用程序来构建n阶魔方阵。明明的问题可以归结为:给你一个阶数n,请你按照题目中描述的方法,构造出n阶魔方阵。

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅占一行,每行仅包括一个正整数n(1≤n≤19,且n是奇数),表示要构造的魔方阵阶数。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将每组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。输出时,每组运算结果为n阶魔方阵。每组运算结果与其后一组运算结果之间有一个空行,最后一组运算结果后面没有空行。 注:通常,显示屏为标准输出设备。

总结:

1. 将构建的魔方阵存入 arr[n][n] 中,i,j 存储现在位置的值在数组中的下标,pre_i,pre_j 存储上一个数在数组中的下标

2. 从数字2开始直到n * n,令i = pre_i - 1,j = pre_j + 1,根据规则三,若 i < 0,则 i = n - 1;根据规则四,若 j >= n,则 j = 0;根据规则五,若按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则 i = pre_i + 1(若 i 出界,则令 i = 0),j = pre_j

3. 对数字2及以后的每个数字 k,得到合适的 i,j 后,将 k 存入 arr[i][j],令pre_i = i,pre_j = j,进行下一个数字的操作

#include <stdio.h>
int main(){
    int n;
    while(scanf("%d", &n) != EOF){
        int arr[n][n];
        for(int a = 0; a < n; a++){
            for(int b = 0; b < n; b++)
                arr[a][b] = 0;
        }
        int i = 0, j = n / 2;
        arr[i][j] = 1;//规则一
        int pre_i = 0;//上一个数在数组的行坐标
        int pre_j = n / 2;//上一个数在数组的列坐标
        for(int k = 2; k <= n * n; k++){
            i = pre_i - 1;//规则二
            j = pre_j + 1;
            if(i < 0)//规则三
                i = n - 1;
            if(j >= n)//规则四
                j = 0;
            if(arr[i][j] != 0 || (pre_i == 0 && pre_j == n-1)){//规则五
                //把下一个数放在上一个数的下面
                i = pre_i + 1;
                j = pre_j;
                //处理边界
                if(i >= n) i = 0;
            }
            arr[i][j] = k;
            pre_i = i;
            pre_j = j;
        }
        for(int a = 0; a < n; a++){
            for(int b = 0; b < n; b++){
                printf("%d", arr[a][b]);
                if(b < n - 1)
                    printf(" ");
                else
                    printf("\n");
            }
        }
        printf("\n");
    }
    return 0;
}
 



 

人机接口为人们提供使用计算机的途径。人机接口的一个例子是键盘,让人们向计算机输入命令和向特定的应用输入文字。人机接口技术研究的多样性与计算机用户和应用的多样性一致。然而,统一的主题是开发更优界面和其有效性的实验评估。例子包括改善残障人士使用计算机的途径,简化程序使用,为虚拟现实开发三维的输入输出设备,改善手写和语音识别,为航空仪表开发前导显示器,关键信息例如速度,高度和朝向都显示在飞行员视窗前的屏幕上。研究的另一领域被称为可视化,与图形展示大规模数据以致于人们可以理解它的关键属性有关。

V.计算机科学与其他学科的联系\n理论计算机科学从数学和逻辑学中借鉴了很多方法。数字计算的研究与数字分析的数学研究重叠。计算机结构分析师工作与设计计算机电路的电力工程师紧密合作。

除了这些理论联系,在AI研究和心理学,神经生理学和语言学中也有很强的联系。人机接口研究也和心理学有联系。机器人专家在设计新的机器人时与机械工程师和生理学加共同工作。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐