C/CPP 基础练习题多维数组,矩阵转置,杨辉三角详解
- 2022 年 8 月 31 日 山东
本文字数:3241 字
阅读完需:约 11 分钟
多维数组
1. 矩阵转置
输入一个数字构成的矩形, 将矩形的值进行转置后打印
输入:
第一行 正整数 n(1<n<10), 表示矩阵的边长
随后输入一个矩阵
输出:
转置后的矩阵
样例输入:
3
1 2 3
4 5 6
7 8 9
样例输出:
1 4 7
2 5 8
3 6 9
2. 颈椎病治疗
最近云海学长一直对着电脑改 bug, 颈椎不舒服, 希望各位小伙伴帮云海学长治治
提供一张图片, 将图片旋转后再发给云海学长, 这样学长看图的时候就需要歪着脖子, 时间久了, 颈椎病就治好了
输入一个数字构成的矩形, 将矩形的值进行 90 度旋转后打印
输入:
第一行 正整数 n(1<n<10), 表示矩阵的边长
随后输入一个矩阵
输出:
90 度旋转后的矩阵
样例输入:
3
1 2 3
4 5 6
7 8 9
样例输出:
7 4 1
8 5 2
9 6 3
3. 杨辉三角
输入 n(1<n<10), 打印高度为 n 的杨辉三角
样例输入: 5
样例输出:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
*4. 包围圈
东东哥在一场军事演练中, 需要对一片正方形森林进行排查,
为了防止被包围, 东东哥需要先排查外围才能进一步深入
输入: 正整数 n(1<n<10), 表示森林的边长
输出: 东东哥排查森林的顺序
样例输入:
4
样例输出:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
解答
1.矩阵转置
#include<iostream>
using namespace std;
const int N = 10;
//按数字顺序生成二维数组
void FuZhi(int n,int a[][10])
{
int k = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
k++;
a[i][j] = k;
}
}
}
//转置,行和列互换
void ZhuanZ(int n,int a[][N])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (i > j)
{
int t = a[i][j];
a[i][j] = a[j][i];
a[j][i] = t;
}
}
}
}
//打印
void Print(int n,int a[][10])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout<<a[i][j];
}
cout << endl;
}
}
int main()
{
int n; cin >> n;
if (n > 1 && n <= N)
{
int a[N][N];
FuZhi(n, a);
Print(n, a);
cout << "转置后:" << endl;
ZhuanZ(n, a);
Print(n, a);
}
system("pause"); return 0;
}
// 矩阵转置
void Demo61() {
//--变量声明--
// 矩阵边长, 矩阵本身, 转置后数组
int size, arr[10][10], result[10][10];
//--接收输入--
scanf_s("%d", &size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
scanf_s("%d", &arr[i][j]);
}
}
//--数据处理--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
result[j][i] = arr[i][j];
}
}
//--输出--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d ", result[i][j]);
}
printf("\n");
}
}
✨2.矩阵 90°转置
// 颈椎病
void Demo62() {
//--变量声明--
// 矩阵边长, 矩阵本身, 转置后数组
int size, arr[10][10], result[10][10];
//--接收输入--
scanf_s("%d", &size);
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
scanf_s("%d", &arr[i][j]);
}
}
//--数据处理--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
result[j][size - i - 1] = arr[i][j];
}
}
//--输出--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d ", result[i][j]);
}
printf("\n");
}
}
详细分析:
//数组下标变化:
假设size为3
0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
->
0 1 2
0 7 4 1
1 8 5 2
2 9 6 3
x1 y y x2
[0][0]->[0][2]
[0][1]->[1][2]
[1][2]->[2][1]
[2][1]->[1][0]
//规律:
x转y ,y转x
x转y时 size - x = y,由于下标开始值为0,所以size - 1 - x = y
y转x时 y = x
如上,y下标原封替换x坐标,但是x下标需要被size - 1 减后才能作为新数组的y下标。
3.杨辉三角
#include<iostream>
using namespace std;
void Print(int n, int a[][10]);
void YH(int n)
{
int a[10][10];
//计算杨辉三角, 以下三角矩阵的形式存放在二维数组
for (int i = 0; i < n; i++) {
a[i][0] = 1;
a[i][i] = 1;
for (int j = 1; j < i; j++)
a[i][j] = a[i - 1][j - 1] + a[i - 1][j]; //i不可能取值为0导致地址越界
}
Print(n,a);
}
void Print(int n,int a[][10])
{
for (int i = 0; i < n; i++) {
for (int j = 1; j <= n - 1 - i; j++) //打印每行开始的空格
cout << " ";
for (int j = 0; j <= i; j++) //每行打印的数据个数
cout << a[i][j] << " ";
cout << endl;
}
}
int main() {
int n; cin >> n;
YH(n);
system("pause"); return 0;
}
// 杨辉三角
void Demo63() {
//--变量声明--
// 杨辉三角的高度
int n;
// 存储用数组, 注意杨辉三角只会占用一半的空间, 所以这里可以用malloc动态分配来避免空间浪费
int arr[10][10];
//--接收输入--
scanf_s("%d", &n);
arr[0][0] = 1;
//--数据处理--
// 左右两侧数据直接填充即可
for (int i = 1; i < n; i++) {
arr[i][0] = arr[i][i] = 1;
for (int j = 1; j < i; j++) {
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
}
}
//--输出--
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
✨4.包围圈
// 包围圈
void Demo64() {
//--变量声明--
int size, tree[10][10];
// 当前坐标xy, 移动方向toward 0左 1下 2右 3上, 填充数
// 注意 由于第一次探查前会先移动 x++ 所以x需要修正为-1
int x = -1, y = 0, toward = 0, num = 0;
// 一个方向的移动步数
int s;
//--接收输入--
scanf_s("%d", &size);
s = size;
//--数据处理--
// 移动规律 如果是4 则是4+3+3+2+2+1+1 = 16 同理 如果是5 5+4+4+3+3+2+2+1+1
// 外部循环: 每奇数次循环, 最大步数-1. 一个方向移动完后 对方向进行修改
// 内部循环: 循环(步数)次, 每次移动根据方向对xy进行修改
for (int i = 0; num<size*size; i++) {
// 奇数次循环 最大步数-1
if (i % 2 == 1) s--;
for (int j = 0; j < s; j++) {
// 获取方向并移动
switch (toward) {
case 0:
x++;
break;
case 1:
y++;
break;
case 2:
x--;
break;
case 3:
y--;
break;
}
tree[y][x] = ++num;
}
// 改变方向 注意 当toward为3 也就是向上时, 需要取模操作 也就是变为0
// (1+1) %4 = 2 (3+1) %4=0
toward = (toward + 1) % 4;
}
//--输出--
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d ", tree[i][j]);
}
printf("\n");
}
}
版权声明: 本文为 InfoQ 作者【CtrlX】的原创文章。
原文链接:【http://xie.infoq.cn/article/ef7537ae9169845739bfb6f74】。文章转载请联系作者。
CtrlX
Pain is inevitable,suffering is optional 2022.08.01 加入
【个人网站】ctrlx.life 【联系方式】微信:gitctrlx 【软件技能】前端,C++,Python,研究网络工程,数据结构与算法。
评论