https://onlinegdb.com/zZAhcdpVO

疑问写在里面,老师请帮忙看看

include<stdio.h>
#include<string.h>
typedef struct
{
char name[20];
char ID[20];
int rpt[5];
double ave;
int tot;
}stu;
int main()
{
stu s1[101];
int n; scanf("%d", &n);
for (int m = 0; m < n; m++) {
getchar();
fgets(s1[m].name,25 , stdin);
fgets(s1[m].ID, 25, stdin);
char*find1 = strchr(s1[m].name, '\n');
char*find2 = strchr(s1[m].ID, '\n');
if (find1) *find1 = '\0';
if (find2) *find2 = '\0';
//gets(s1[m].name);
//gets(s1[m].ID);
for (int i = 0; i < 5; i++)
scanf("%d", &s1[m].rpt[i]);
printf("Name:%s\nID:%s\nScore:", s1[m].name, s1[m].ID);
s1[m].tot = 0;
for (int i = 0; i < 4; i++)
{
printf("%d ", s1[m].rpt[i]);
s1[m].tot += s1[m].rpt[i];
}
printf("%d\n", s1[m].rpt[4]);
s1[m].tot += s1[m].rpt[4];

if (s1[m].tot > 0) s1[m].ave = s1[m].tot / 5.0;
else s1[m].ave = 0.00;
printf("average:%.2f total:%d\n\n", s1[m].ave, s1[m].tot);
}
return 0;
}

代码如上,最后一个测试点出现运行时错误,老师能帮忙看下吗?万分感谢

第十一次编程作业总结

    这次编程作业主要是对于二维数组的一些操作,各个题目的情况如下,对数组操作要特别注意不能够越界访问。

6-24

  • 编译错误: 缺少;在语句后

  • 部分正确:

    • 逻辑错误,题目中只是说了n,m的取值范围是1~100, 不能将初始最小值设定为100然后和其他元素进行比较来求最小值。

    • 对于最小值的假定应该在外循环中指定,而不是在内循环,本题中使用2个嵌套循环。

    • 应该遍历完整个内层循环后,才能找到最小值,所以对于找到每一列的最小值的赋值语句在外层循环。

    • 在内层循环开始前,指定一个最小值为一个数字,比如1000的做法是不对的,如果这一列的最小值大于1000,那么得到的最后这一列的最小值为1000,这显然是不对的。

  • 这个题目的思路为:要求一列的最小值,可以假定该列的第一个元素最小,然后与该列的其他元素进行比较,更新这个最小值即可。

// 列数为m, 行为n
// void findMin(int matrix[][MAX], int x[], int n,int m)
void findMin(int (*matrix)[MAX], int x[], int n,int m)
{
   int temp_min_index = 0;
   for (int i = 0; i < m; i++) // 列   循环遍历每一列
  {
       temp_min_index = 0; // 假定该列的最小元素在第一行 , 用来记录该列中最小值所在的行
       for (int j = 1; j < n; j++)// 行
      {
           if (matrix[j][i] < matrix[temp_min_index][i]) // 在该列中发现某一行的元素更小
          {
               temp_min_index = j; // 更新该列中最小值所在的行
          }
      }
       x[i] = matrix[temp_min_index][i]; // 将第i列最小值赋值给 x[i]
  }
}

7-44

  • 段错误:数组访问越界

  • 编译错误:变量未定义就使用

  • 格式错误,输出格式错误

  • 在定义数组时候,如下写法是错误的,m,n的值是未知的

     int m,n,l;
    int a[m][n];
    scanf("%d%d",&m,&n);

    // 也不建议如下定义
    int m,n,l;
    scanf("%d%d",&m,&n);
    int a[m][n];
    // 建议定义方式
    #define MAX 100
    int m,n,l;
    int a[MAX][MAX];
    scanf("%d%d",&m,&n);
    // 只对 a[i][j]访问 (i >= 0 and i < m and j >= 0 and j < n)
  • 本题中要求转置,转置变换后a[i][j] = a[j][i],即将行列互换,本题中只需将二维数组按列优先的顺序输出即可,但是要注意格式

    #include<stdio.h>
    #define MAX 100
    int main(void)
    {
       int a[MAX][MAX];
       int m, n;
       scanf("%d%d", &m, &n);
       for (int i = 0; i < m; i++)
      {
           for (int j = 0; j < n; j++)
          {
               scanf("%d", &a[i][j]); // i行j列的元素
          }
      }
       // 按列优先输出
       for (int i = 0; i < n; i++)
      {
           for (int j = 0; j < m; j++)
          {
               if (j != 0)
              {
                   printf(" ");
              }
               printf("%d", a[j][i]); // j行i列的元素
          }
           if (i != n - 1)
               printf("\n");
      }
       return 0;
    }

    7-45

  • 段错误: 数组访问越界

  • 答案错误: 逻辑错误

  • 格式错误 输出格式错误 int A[][]作为参数传递必须指定第二维的长度

  • 本题可以将每次得到的一条销售记录累加到二维数组的正确位置来解答

#include<stdio.h>
int main(void)
{
   float output[6][5] = {{0.0}}; // 销售员-产品 二维数组
   int n;
   scanf("%d", &n);
   int salerId, productId;
   float sold;
   while (n > 0)
  {
       scanf("%d%d%f", &salerId, &productId, &sold);
       // 将销售额累加到合适的位置 下标减1, 数组下标从0开始
       output[productId - 1][salerId - 1] += sold;
       output[5][salerId - 1] += sold; // 产品的总销售额度
       output[productId - 1][4] += sold; // 销售员的总销售额度
       n--;
  }
   
   // 计算最右下角的元素 选定最后一列累加,也可选定最后一行进行累加
   for (int i = 0; i < 5; i++)
  {
       output[5][4] += output[i][4];
  }
   
   // 打印,注意输出格式 \t %.1f 等格式
   for (int i = 0; i < 6; i++)
  {
       for (int j = 0; j < 4; j++)
      {
           printf("%.1f\t", output[i][j]);
      }
       printf("%.1f\n", output[i][4]);
  }
   return 0;
}

7-46

  • 编译错误

  • 部分正确、逻辑错误

  • 这个题目主要是确定要计算那些数组元素的和,在计算的时候要防止数组越界,可以通过下标情况进行分类讨论,使用if else if else结构语句,也可以考虑一种通用的情况,如下代码。注意给定的元素位置和数组下标之间的关系

#include<stdio.h>
#define MAX 10
int main(void)
{
   int m, n;
   int a[MAX][MAX];
   scanf("%d%d", &m, &n);
   int row,col;
   int sum = 0;
   for (int i = 0; i < m; i++)
  {
       for (int j = 0; j < n; j++)
      {
           scanf("%d", &a[i][j]);
      }
  }
   
   scanf("%d%d", &row, &col);
   // 数组下标从0开始,相应位置的元素所在的数组下标
   row = row -1;
   col = col -1;
   // 统计包括该元素在内的9个点的和(实际点数小于等于9)
   for (int i = row - 1; i < row + 2; i++)
  {
       for (int j = col - 1; j < col + 2; j++)
      {
           if (i >= 0 && i < m && j >= 0 && j < n) // 可以通过判断数组是否越界,来判断是否存在该点
          {
               sum += a[i][j];
          }
      }
  }
   sum -= a[row][col]; // 减去数组元素本身,统计其周围的点的和
   printf("%d", sum);
}

7-47

主要思路:这道题的主要思路是遍历每一行,找到一行中最大的数,然后再判断这个数是不是在其列中是最小的数。因为如果一个矩阵有鞍点,那么这个鞍点一定是唯一的。如果找到这样的数,那么循环就可以停止,如果遍历所有行都没有这样的数,就说明该矩阵不存在鞍点。测试用例保证了同行或者同列没有相等的值,但不同行不同列可能有相等的值。

循环错误:在嵌套循环时,内部循环的循环变量和外层不能是同一个。这个之前的总结中也提起过。

 

7-48

主要思路:本题的思路比较简单,计算每一行的平均数然后排序,按照排序后的结果输出每一行。重点是具体如何操作。一种方法是定义两个一维数组,一个来存储每行的平均数(或者每一行的和),另一个来存储每个平均数的下标。然后对平均数(或者和)进行排序的时候,更改相应另一个数组的值。这样操作之后,存储下标的数组存储的就是平均数从小到大的行数。按照这个存储下标的数组来输出这个矩阵就可。还有就是直接在原矩阵上操作,但还是需要一个计算平均数的数组,在排序的时候,只要前一行的平均数比后一行要大(大于而不是大于等于),就将存储平均数的数组以及矩阵的行进行交换,保证存储平均数的数组的下标与矩阵的行相匹配。

 

7-49

主要思路:可以注意到,对于从右上至左下每一斜的元素,其下标的横纵坐标之和是相等的,元素从上至下不是递增就是递减的,对于横纵坐标之和sum,若sum是偶数,则按照矩阵从右上至左下元素的值是递增的,若是奇数,则是递减的。可以根据这个规律从第一个元素a[0][0]=1(矩阵的行和列都从0开始)开始来形成这个矩阵。对于一个n*n的矩阵,从sum=0到sum=2*n-2需要循环2*n-1次。此外需要注意横纵坐标的范围,对于每一个sum并不是横坐标从0开始到sum。对于上三角矩阵(包括对角线),sum<=n-1时,每一斜,横坐标是从0到sum;而对于剩下的下三角(不包括对角线),sum>n-1时,横坐标从i到n-1,i=sum-n-1。

老师,我自行设计数据测试了几次都没问题,但是在PTA上只有80分。能帮忙看一下或提供一些数据吗?感谢。

https://onlinegdb.com/5oJFNU4eO

徐老师,这个第一题要求用递归算法,我在CSDNhttps://blog.csdn.net/qq_43765564/article/details/85345448上找到了一个类似的代码,但是其中void函数需要调用一个指针不是很理解这个含义,老师能否帮忙看一下这段代码?感谢感谢