PTA-2023第十二次练习题目题解(祝大家机考顺利)
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