Bootstrap

C语言刷题小结---矩阵篇

电影黑客帝国有很多这样的场景

用矩阵表示我们看到的一切!

而在编程中矩阵是用数组来表示的

目前小作者还只是学习编程初学者,很多知识内容都还没有学习。但相信每一个学习编程的小伙伴在做C语言方面的练习时都会遇到有关矩阵相关的题目,以下是小作者总结的有关矩阵的题目,以供大家学习总结。

1.矩阵的创建

2.矩阵元素定位

3. 图像相似度

4.矩阵相等判断

5.上矩阵三角形判断

6.矩阵转置

7.矩阵交换

1.矩阵的创建

输入描述:第一行输入两个整数 n 和 m ,第二行包含 n*m 个整数(1<=n<=10,1<=m<=10)

输出描述:输出规划后 n 行 m 列的矩阵,每个数的后面有一个空格。

#include<stdio.h>
int main()
{
	int n = 0;
	int m = 0;
	printf("请输入你要创建的矩阵大小 n 和 m :\n");
	scanf("%d %d", &n, &m);
	int arr[20] = { 0 };
	int i = 0;
	printf("请依次输入矩阵元素:\n");
	for (i = 0;i < n * m;i++)
	{
		scanf("%d", &arr[i]);
	}
	for (i = 0;i < n * m;i++)
	{
		printf("%d ", arr[i]);
		if (((i + 1) % m == 0))
		{
			printf("\n");
		}
	}
	return 0;
}

运行结果:

 

题目分析:该题整体比较简单。需要注意到的点就是矩阵下表是从0开始的,所以换行时需要 i +1 才可以对 m 进行取模运算,以达到换行的目的。

2.矩阵元素定位

输入描述:

第一行包含两个数 n 和 m ,表示这个矩阵包含 n 行 m 列。从2到 n+1 行,每行输入 m 个整数,用空格分隔,共输入 n*m 个数,表示矩阵的元素。接下来一行输入 x 和 y ,用空格分隔,表示想要得到的元素的位置。(1 <= x <= n <=10 , 1 <= y <=m <= 10)

输出描述:

一行,输出一个整数,即想要得到元素的位置的值。

#include<stdio.h>
int main()
{
	int n = 0;
	int m = 0;
	int arr[10][10] = { 0 };
	printf("请输入矩阵的大小 n 和 m :\n");
	scanf("%d %d", &n, &m);
	int i = 0;
	int j = 0;
	printf("请依次输入矩阵元素:\n");
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < m;j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}
	int x = 0;
	int y = 0;
	printf("请输入你要查找元素的坐标:\n");
	scanf("%d %d", &x, &y);
	printf("%d\n", arr[x - 1][y - 1]);
	return 0;
}

运行结果:

 题目分析:该题相对来说也是比较简单。需要注意的是输入坐标查找矩阵元素时用户并不一定知道数组坐标是从0开始的,所以打印坐标时应该用 arr[ i -1 ][ j - 1] ,而不是 arr[ i ][ j ]。

3.图形相似度

题目描述:

第一行包含两个整数 m 和 n , 表示图像的行数和列数,用单个空格分开。1 <= m <=100 ,1 <= n <=  100 。之后 m 行,每行 n 个整数 0 或 1,表示第一幅黑白图像上各像素点的颜色,相邻两个数用单个空格分开。之后 m 行每行 n 个整数 0 或 1 ,表示第二幅黑白图像上各像素点的颜色,相邻两个数用空格隔开。

输出描述:

一个实数,表示相似度(以百分比的形式给出),精确到小数点后两位。

#include<stdio.h>
int main()
{
	int m = 0;
	int n = 0;
	int arr1[100][100] = { 0 };
	int arr2[100][100] = { 0 };
	printf("请确定两个矩阵的大小 m 和 n :\n");
	scanf("%d %d", &m, &n);
	int i = 0;
	//读取第一个矩阵的数据
	printf("请输入第一个矩阵的元素:\n");
	for (i = 0;i < m;i++)
	{
		int j = 0;
		for (j = 0;j < n;j++)
		{
			scanf("%d", &arr1[i][j]);
		}
	}
	//读取第二个矩阵的数据
	printf("请输入第二个矩阵的元素:\n");
	for (i = 0;i < m;i++)
	{
		int j = 0;
		for (j = 0;j < n;j++)
		{
			scanf("%d", &arr2[i][j]);
		}
	}
	//求相似度
	int count = 0;
	for (i = 0;i < m;i++)
	{
		int j = 0;
		for (j = 0;j < n;j++)
		{
			if (arr1[i][j] == arr2[i][j])
			{
				count++;
			}
		}
	}
	printf("两图像的相似度位:\n");
	printf("%.2lf\n", count * 100.0 / (m * n));
	return 0;
}

运行结果:

题目分析:该题的主要难点在于理解用 0 和1 组成的矩阵来表示图像的像素点,以及如何计算两个图像的相似度(注意相似度是保留两位小数) 。

4.矩阵相等判断

输入描述:

第一行包含两个数 n 和 m ,表示两矩阵包含 n 行 m 列。从2到 n+1 行,每行输入 m 个整数,用空格分隔,共输入 n*m 个数,表示矩阵的元素。

输出描述:

判断两矩阵是否相等。

#include<stdio.h>
int main()
{
	int arr1[10][10] = { 0 };
	int arr2[10][10] = { 0 };
	int n = 0;
	int m = 0;
	printf("请输入两矩阵的行数和列数 n 和 m :\n");
	scanf("%d %d", &n, &m);
	int i = 0;
	int j = 0;
	printf("请输入第一个矩阵的元素:\n");
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < m;j++)
		{
			scanf("%d", &arr1[i][j]);
		}
	}
	printf("请输入第二个矩阵的元素:\n");
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < m;j++)
		{
			scanf("%d", &arr2[i][j]);
		}
	}
	//比较
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < m;j++)
		{
			if (arr1[i][j] != arr2[i][j])
			{
				printf("两矩阵不相等\n");
				return 0;
			}
		}
	}
	printf("两矩阵相等\n");
	return 0;
}

运行结果:

 题目分析:该题中需要注意的是如何更简便的得到结果,相对于判断相等,判断不相等要容易的多。

5.上矩阵三角形判断

题目描述:

请编写一个程序,判断一个 n 阶方阵是否为上三角矩阵。上三角矩阵即主对角线以下的元素都为0的矩阵,主对角线为从矩阵的左上角值右下角的连线。

输入描述:

第一行包含一个整数 n ,表示一个方阵包含 n 行 n 列,用空格分隔。(1 <= n <= 10)从2到 n + 1 行,每行输入 n 个 整数,用空格分隔,共输入 n * n 个数。

输出描述:

判读是否为上三角形矩阵,若是则打印该矩阵,否则只需判断即可。

#include<stdio.h>
int main()
{
	int n = 0;
	int arr[10][10] = { 0 };
	printf("请输入方阵的阶数 n :\n");
	scanf("%d", &n);
	int i = 0;
	int j = 0;
	printf("请输入方阵的元素:\n");
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < n;j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < n;j++)
		{
			//找左下角的坐标

			if (i>j)
			{
				if (arr[i][j] != 0)
				{
					printf("不是上三角形矩阵\n");
					return 0;
				}
			}
		}
	}
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < n;j++)
		{
			printf("%d ", arr[i][j]);
			if (j + 1 == n)
			{
				printf("\n");
			}
		}
	}
	printf("是上三角形矩阵\n");
	return 0;
}

运行结果:

题目分析:

该题的重点是如何判断上三角形矩阵,突破点在以主对角线为分界线的上下坐标的区别。在主对角线上横坐标与纵坐标是相等的,即 i == j;而主对角线以上横坐标小于纵坐标,即 i < j ;而在主对角线以下横坐标大于纵坐标,即 i > j。

仅仅是语言描述还是太抽象,上图解:

ju

 6.矩阵转置

输入描述:

第一行包含两个数 n 和 m ,表示两矩阵包含 n 行 m 列。从2到 n+1 行,每行输入 m 个整数,用空格分隔,共输入 n*m 个数,表示矩阵的元素( n 和 m 都是小于等于10)。

输出描述:

打印原矩阵,对矩阵进行转置,即将 n 行 m 列的矩阵转置为 m 行 n 列的矩阵,并打印转置后的矩阵。

 

#include<stdio.h>
int main()
{
	int n = 0;
	int m = 0;
	int arr[10][10] = { 0 };
	int i = 0;
	int j = 0;
	printf("请输入矩阵行数 n 和列数 m :\n");
	scanf("%d %d", &n, &m);
	printf("请依次输入矩阵元素:\n");
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < m;j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}
	//打印原矩阵
	printf("原矩阵为:\n");
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < m;j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	//转置
	// n行m列转换为m行n列
	printf("转置后的矩阵为:\n");
	for (i = 0;i < m;i++)
	{
		for (j = 0;j < n;j++)
		{
			printf("%d ", arr[j][i]);
		}
		printf("\n");
	}
	return 0;
}

运行结果:

 

 题目分析:

该题的重点在于转置的过程。矩阵的转置不仅仅是单纯的将行数和列数交换以下,还应该注意到坐标的变化,即 arr[ i ][ j ] 转变为 arr[ j][ i ]。

7.矩阵的交换

输入描述:

第一行包含两个数 n 和 m ,表示两矩阵包含 n 行 m 列。从2到 n+1 行,每行输入 m 个整数,用空格分隔,共输入 n*m 个数,表示第一个矩阵的元素( n 和 m 都是小于等于10)。

接下来一行输入 K ,表示要执行 K 次操作( K 的范围是大于等于1小于等于5)。接下来有 K 行,每行包括一个字符 t 和两个数 a 和 b ,中间用空格分隔,t 代表需要执行的操作,当 t 为字符 ' r ' 时代表进行行行变换,当 t 为字符 ' c ' 时代表进行列列变换,a 和 b 为需要互换的行或列(1 <= a<= b <= n <= 10,1 <= a <= b <=m <= 10)。

输出描述:

输出 n 行 m 列,为矩阵交换后的结果。每个数后面有一个空格。

#include<stdio.h>
int main()
{
	int n = 0;
	int m = 0;
	int arr[10][10] = { 0 };
	printf("请输入矩阵的大小行数 n 和列数 m :\n");
	scanf("%d %d", &n, &m);
	//输入矩阵数据
	int i = 0;
	int j = 0;
	printf("请输入矩阵元素:\n");
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < m;j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}
	int K = 0;//操作的次数
	printf("请输入交换的次数:\n");
	scanf("%d", &K);//1\n
	int r = 0;
	printf("请输入具体操作:(r代表行交换,c代表列交换)被交换的位置a和b\n");
	for (r = 0;r < K;r++)
	{
		//一次的交换
		char t = 0;
		int a = 0;
		int b = 0;
		//getchar()消除上次输入留下的\n
		scanf(" %c %d %d", &t, &a, &b);//scanf()前加一个空格,消除\n
		if (t == 'r')
		{
			//行的交换
			i = 0;
			for (i = 0;i < m;i++)
			{
				//arr[a-1][i]
				//arr[b-a][i]
				int tmp = arr[a - 1][i];
				arr[a - 1][i] = arr[b - 1][i];
				arr[b - 1][i] = tmp;
			}
		}
		else if (t == 'c')
		{
			//列的交换
			for (i = 0;i < n;i++)
			{
				//arr[i][a-1]
				//arr[i][b-a]
				int tmp = arr[i][a - 1];
				arr[i][a - 1] = arr[i][b - 1];
				arr[i][b - 1] = tmp;
			}
		}
	}
	//打印交换后的矩阵
	for (i = 0;i < n;i++)
	{
		for (j = 0;j < m;j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

运行结果:

 

题目分析:

这道题相对来说较为复杂,除了需要注意消除输入 K 时附带的 \n 等细节以外,还需要注意到矩阵的交换形式,即坐标之间的转变交换的坐标都是对应的 a-1 和 b-1。

 上图解:

 在文章的最后,每一个读者都应该收到一个大大的赞

 

;