### 湘潭大学《C语言程序设计实践》习题整理
#### 题目一:矩阵转置
**题目背景**
本题来源于湘潭大学计算机科学与技术、网络工程、软件工程专业开设的《C语言程序设计实践》课程中的Online Judge网站。题目要求实现矩阵的转置,并特别强调了对于稀疏矩阵的处理方式。
**知识点**
1. **矩阵转置的基本概念**
- 矩阵转置是指将一个矩阵A的行变为新矩阵B的列,而矩阵A的列变为新矩阵B的行。
- 具体来说,如果矩阵A的一个元素表示为aij,那么转置后的矩阵B的对应元素则表示为bji。
2. **稀疏矩阵及其存储**
- 稀疏矩阵是指矩阵中大多数元素为0的情况。
- 对于稀疏矩阵,通常采用三元组表的形式进行存储,即用(i, j, aij)来表示矩阵中非零元素的位置及其值,其中i和j分别代表该非零元素在矩阵中的行和列索引,aij则是该位置上的数值。
3. **三元组表的排序**
- 在处理稀疏矩阵时,通常需要按照一定的顺序对三元组进行排序。题目中要求按照“行优先”的顺序对三元组进行排序,这意味着首先按照行索引i进行排序,在行索引相同的情况下再按照列索引j进行排序。
4. **C语言编程实现**
- 使用结构体来定义三元组,包括行索引、列索引以及对应的值。
- 利用C语言的标准库函数`sort()`来对结构体数组进行排序,这里需要自定义比较函数`cmp()`来实现“行优先”的排序规则。
- 通过循环读取输入并存储到结构体数组中,然后进行排序,最后输出转置后的矩阵。
**示例代码分析**
```c
#include<bits/stdc++.h>
using namespace std;
// 定义结构体存储矩阵元素
struct mat {
int x, y, v;
} a[10000];
// 自定义比较函数
bool cmp(mat c, mat d) {
if (c.y == d.y)
return c.x < d.x;
else
return c.y < d.y;
}
int main() {
int i, t, n, m, k;
cin >> t;
while (t--) {
cin >> n >> m >> k;
for (i = 0; i < k; i++)
cin >> a[i].x >> a[i].y >> a[i].v;
sort(a, a + k, cmp);
for (i = 0; i < k; i++)
cout << a[i].y << '' << a[i].x << '' << a[i].v << endl;
cout << endl;
}
return 0;
}
```
#### 题目二:平方数对计数
**题目背景**
同样来自湘潭大学的《C语言程序设计实践》课程,本题要求统计一个整数集合中满足特定条件的平方数对的数量。
**知识点**
1. **平方数对的定义**
- 给定一个无重复元素的整数集合A,如果存在x, y ∈ A且y = x * x,则称<x, y>为一个平方数对。
2. **算法设计**
- 可以采用暴力法遍历集合中的每个元素x,并检查x * x是否也在集合中。
- 为了提高效率,可以预先计算所有可能的平方数,并存储在一个哈希表中,以便快速查询。
3. **输入输出格式**
- 输入包括多个测试样例,每个样例包含两行:第一行是一个非负整数n表示集合中元素的数量;第二行是n个整数,表示集合中的元素。
- 输出对于每个样例,输出一行结果,表示满足条件的平方数对的数量。
**示例代码框架**
```c
#include <stdio.h>
#include <stdbool.h>
// 假设集合大小不超过1000
#define MAX_N 1000
#define MAX_SQRT 100000000
bool isSquare[MAX_SQRT + 1];
void preprocessSquares() {
// 预处理所有可能的平方数
for (int i = 1; i * i <= MAX_SQRT; i++) {
isSquare[i * i] = true;
}
}
int main() {
preprocessSquares();
int n;
while (scanf("%d", &n) != EOF && n != 0) {
int count = 0;
int arr[MAX_N];
// 读取集合元素
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
// 统计平方数对数量
for (int i = 0; i < n; i++) {
if (isSquare[arr[i]] && arr[i] * arr[i] <= MAX_SQRT) {
for (int j = 0; j < n; j++) {
if (arr[i] * arr[i] == arr[j]) {
count++;
break;
}
}
}
}
printf("%d\n", count);
}
return 0;
}
```
以上是两个题目中涉及的主要知识点和相应的示例代码分析。通过这些练习可以帮助学生更好地理解和掌握C语言程序设计的基本原理和技术要点。