PTA-2023第十二次练习题目题解

发布时间 2023-12-08 21:30:26作者: 一只傲娇璇

PTA-2023第十二次练习题目题解

以下代码已做防抄袭处理,切勿抄袭。

注意:手机端因为屏幕限制,代码会有(不希望的)换行。解决方案:1.建议使用电脑端打开。2.点击代码进入全屏观看。

6-24 实验8_3_设计函数

利用冒泡排序的思想,将每一列的最小值放到每列的最后一个位置。

void findMin(int M[][MAX],int q[];int n,int m)
{
        for(int i=  0;i<m;i++)//i控制需要找最大值的列数
        {
                for(int k  = 0;k<n-1;k++)//k控制行数
                {
               	  //如果M[k][i]<M[k+1][i],就交换位置
               	  //循环一次之后,就会将最小值放到当前列的最后一个位置(和冒泡排序第二层循环的作用相同)
                        if(M[k][i]<M[k+1][i])
                        {
                            int x;
                            x = M[k][i];
                            M[k][i] = M[k+1][i];
                           M[k+1][i] = x;
                        }
                }
        }

    for(int i = 0;i<m;i++)
    {
        q[i] = M[n-1][i];//将每一列的最后一个数储存到p[]中
    }
}

7-44 实验8_1_矩阵转置

将矩阵读入二维数组后,直接按列的顺序输出

先输出第一列的第一个数,然后输出第一列的第二个数.....输出完这一列后,同理开始输出下一列数。

那么输出的矩阵就是转置之后的矩阵。

#include <stdio.h>

int main()
{
    //正常读入
    int a[101][101];
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 0;i<n;i++)
    {
        for(int j = 0;j<m;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    //按列的顺序输出
    for(int i = 0;i<m;i++)//i控制列数
    {
        for(int j = 0;j<n-1;j++)//j控制行数
        {
            printf("%d ",a[j][i]);
        }
        printf("%d\n",a[n-1][i]);//注意格式
    }
    return 0;
}

7-45 实验8_2_推销员的便条

题目重点:用列代表销售员,行代表产品

每一次的输入都输入3个数,依次是销售员的代号、产品的代号、这种产品的销售额。

那么我们可以用一个二维数组来储存最后的答案,同时1.二维数组的行号代表产品的产品的代号。2.二维数组的列号代表销售员的代号。3.以上面两个数确定的二维数组中的元素的值代表该种产品的销售额。

这一部分核心代码:

int c, b;//c是销售员的代号,b是产品代号
float x;//x是销售额
scanf("%d %d %f", &c, &b, &x);
a[b][c] += x;//a[产品代号][销售员代号] = 销售额

然后还需要计算每行每列的和。

先计算每一行的和:

for (int i = 1; i <= 5; i++)
	{
		float sum= 0;
		for (int j = 1; j <= 4;j++)
		{
			sum += a[i][j];
		}
		a[i][5] = sum;//将这一行的和放到该行末尾
	}

同理计算每一列的和

for (int i = 1; i <= 5;i++)
	{
		float sum = 0;
		for (int j = 1; j <= 5; j++)
		{
			sum += a[j][i];
		}
		a[6][i] = sum;
	}

最后正常输出就好,完整代码如下:

#include <stdio.h>
float  a[7][7];
int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		int c, b;
		float x;
		scanf("%d %d %f", &c, &b, &x);
		a[b][c] += x;
	}
	
	for (int i = 1; i <= 5; i++)
	{
		float sum= 0;
		for (int j = 1; j <= 4; j++)
		{
			sum += a[i][j];
		}
		a[i][5] = sum;
	}

	for (int i = 1; i <= 5; i++)
	{
		float sum = 0;
		for (int j = 1; j <= 5; j++)
		{
			sum += a[j][i];
		}
		a[6][i] = sum;
	}
	for (int i = 1; i <= 6; i++)
	{
		for (int j = 1; j <= 4; j++)
		{
			printf("%.1f	", a[i][j]);
		}
		printf("%.1f\n", a[i][5]);
	}
	return 0;
}

7-46 实验8_4_矩阵操作

最多周围只有8个数,所以就用if语句分别判断这8个数是否存在就好了。

判断是否存在的条件就是判断下标的范围是否在合法的范围之内。

int n, m;
int a[20][20];
int main()
{
	scanf("%d %d ", &n, &m);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			scanf("%d", &a[i][j]);
		}
	}
	int x, y;
	scanf("%d %d", &x, &y);
    //因为数组的x,y从0开始,所以我们x--,y--;
	x --;
	y --;
	long long sum = 0;
	if (x - 1 >= 0)
	{
		sum += a[x - 1][y];//第一个数
		if (y - 1 >= 0)
		{
			sum += a[x - 1][y - 1];//第二个数
		}
		if (y + 1 < m)
		{
			sum += a[x - 1][y + 1];//第三个数
		}
	}
	if (x + 1 < n)
	{
		sum += a[x + 1][y];//第四个数
		if (y - 1 >= 0)
		{
			sum += a[x + 1][y - 1];//第五个数
		}
		if (y + 1 < m)
		{
			sum += a[x + 1][y + 1];//第六个数
		}
	}
	if(y - 1 >= 0)
	{
		sum += a[x][y - 1];//第七个数
	}
	if (y + 1 < m)
	{
		sum += a[x][y + 1];//第八个数
	}
	printf("%lld\n", sum);
	return 0;
}

7-47 实验8_5_寻找鞍点

我们设计两个函数,

第一个函数:findmax(int i),作用为找到第i行的最大值所在的列数并返回。

第二个函数:check(int x,int j),判断x是否为第j列的最小值

int n, m;
int a[200][200];
int findmax(int i)//找到第i行的最大值所在的列数
{
	int num = 0;//num用来储存最大值所对应的下标
	int maxnum = -2e9;.//maxnum用来储存最大值
	for (int j = 0; j < m; j++)
	{
		if (a[i][j] > maxnum)//如果a[i][j]比当前的maxnum还要大的话,就更新最大值和最大值下标
		{
			num = j;
			maxnum = a[i][j];
		}
	}
	return num;//返回最大值下标
}
bool check(int x,int j)//判断x是否为第j列的最小值
{
    for (int i = 0; i < n; i++)
	{
		if (a[i][j] < x) return false;
	}
	return true;
}
int main()
{
	scanf("%d %d ", &n, &m);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			scanf("%d", &a[i][j]);
		}
	}
	int num = 0;
	for (int i = 0; i < n;i++)
	{
		int j = findmax(i);//找到第i行最大值的下标的列数,储存到j
		if (check(a[i][j], j))//检查a[i][j]是否为第j列的最大值
		{
			printf("The saddle point is (%d,%d)=%d.\n", i, j, a[i][j]);
			num++;//如果是就输出,并标记已经找到了
		}
	}
	if (num ==0 )//如果没找到
	{
		printf("There is no saddle point in the matrix.\n");
	}
	return 0;
}

7-48 实验8_6_矩阵变换

思路是用结构体来储存每一行的数,并储存平均值,最后按照平均值将这几个结构体排序,然后输出。

struct num//构造一个结构体,用来储存第i行的n个元素
{
	int x[110];//储存这一行的n个元素
	double av;//储存这一行的平均值
};
struct num a[110];
//判断两个结构体的平均值是否满足条件
bool cmp(struct num x, struct num y)
{
	return x.av <= y.av;
}
//排序函数
void sort(int l, int r)//排序a数组中下标在l,r之间的数
{
    //冒泡排序
	for (int i = l; i < r; i++)
	{
		for (int j = l; j < r; j++)
		{
            //如果前一个结构体的平均值比后一个结构体的平均值大,就交换这两个结构体
			if (!cmp(a[j], a[j + 1]))
			{
				struct num x;
				x = a[j];
				a[j] = a[j + 1];
				a[j + 1] = x;
			}
		}
	}
}
int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		double temp = 0;//temp储存当前输入行的和
		for (int j = 0; j < n; j++)
		{
			scanf("%d",&a[i].x[j]);
			temp += a[i].x[j];
		}
        //储存当前行的平均值
		a[i].av = temp/n;
	}
	sort(0, n-1);//按照平均值从小到大排序
	for (int i = 0; i < n; i++)//输出
	{
		for (int j = 0; j < n-1; j++)
		{
			printf("%d ", a[i].x[j]);
		}
		printf("%d\n", a[i].x[n - 1]);
	}
	return 0;
}

7-49 实验8_7_蛇形矩阵

我们模拟矩阵中的数蛇形填如的方式,将1-n*n的每个数填入数组当中。

1.将整个矩阵分为上半部分和下半部分,每个部分又分为向斜上方填入数据,和向斜下方填入数据两种方式。

2.同时发现,当所填入的斜行是奇数行时,他是斜向上填入,而偶斜行时是向斜下方填入。(行数从0开始)

首先给出,一个坐标(x,y),斜上方的坐标为(x-1,y+1),斜下方的坐标为(x+1,y-1)

那么判断这两个坐标存在的方式就是判断坐标是否越界

首先看奇数行:

if (num % 2 != 0)//如果是奇数行,就斜上方输入数据
		{
            //当斜上方的坐标一直不越界时,就将数字填入,并且更新坐标
			while (i - 1 >= 0 && j + 1 < n)
			{
				a[i--][j++] = k++;//k是一个从0开始的,控制元素值的数;
			}
            //当到达矩阵边界的时候,将元素下边移向下一个斜行
			a[i][j++] = k++;//因为是上半部分奇数行,所以换行的操作为j++;
		}

然后偶数行同理:

		else //向斜下方输入数据
		{
			while (i +1 <n && j - 1 >=0)
			{
				a[i++][j--] = k++;
			}
			a[i++][j] = k++;
		}

以上是上半部分,下半部分也是同理的,但是到达边界时候换行的方式与上半部分恰好是相反的,建议大家结合图形看一下。

if (num % 2 != 0)
		{
			while (i - 1 >= 0 && j + 1 < n)
			{
				a[i--][j++] = k++;
			}
			a[i++][j] = k++;
		}
		else
		{
			while (i + 1 < n && j - 1 >= 0)
			{
				a[i++][j--] = k++;
			}
			a[i][j++] = k++;
		}

以下是完整代码:

int main()
{
	int n;
	scanf("%d", &n);
	int a[110][110];
	int i = 0, j = 0,k = 1;
	int num = 0;
    //上半部分
	for (; num <n; num++)
	{
		if (num % 2 != 0)
		{
			while (i - 1 >= 0 && j + 1 < n)
			{
				a[i--][j++] = k++;
			}
			a[i][j++] = k++;
		}
		else 
		{
			while (i +1 <n && j - 1 >=0)
			{
				a[i++][j--] = k++;
			}
			a[i++][j] = k++;
		}
	}
    //当上半部分结束时,i,j的坐标与下半部分不对应,所以要调整i,j的值
	if (num % 2 != 0)
	{
		i--;
		j++;
	}
	else
	{
		j--;
		i++;
	}
    //开始下半部分
	for (; num < 2*n-1; num++)
	{
		if (num % 2 != 0)
		{
			while (i - 1 >= 0 && j + 1 < n)
			{
				a[i--][j++] = k++;
			}
			a[i++][j] = k++;
		}
		else
		{
			while (i + 1 < n && j - 1 >= 0)
			{
				a[i++][j--] = k++;
			}
			a[i][j++] = k++;
		}
	}
    //输出
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n-1; j++)
		{
			printf("%d ", a[i][j]);

		}
		printf("%d\n", a[i][n - 1]);
	}
	return 0;
}

7-53 实验9_4_句子输出

定义一个char类型二维数组,前一个坐标表示输入字符串对应的数字,后一个坐标储存字符串

int main()
{
	int n;
	scanf("%d", &n);
	char x[20][20];
    //正常读入
	for (int i = 0;i < n;i++)
	{
		scanf("%s", &x[i]);
	}
	for (int i = 0; i < n; i++)
	{
        //a储存要输出的字符串对应的序号
		int a;
		scanf("%d", &a);
		printf("%s\n", x[a]);
	}
	return 0;

}

完结!

第三次机考的题解暂定周日发。

给孩子个赞和关注吧/ww