主页 > 其他  > 

C++蓝桥杯基础篇(六)

C++蓝桥杯基础篇(六)
片头

嗨~小伙伴们,大家好!今天我们来一起学习蓝桥杯基础篇(六),练习相关的数组习题,准备好了吗?咱们开始咯!


第1题  数组的左方区域

这道题,实质上是找规律,我们观察到,可以将绿色的区域分成上下2个部分,因此,我们可以列出2张表。

左方区域---上半部分 ij1020~130~240~350~4i0 ~ i-1

再看另一张表

左方区域---下半部分 ij60~470~380~290~1100i0 ~ 10-i

掌握规律后,一目了然,这道题的代码如下:

//数组的左方区域 //输入一个二维数组m[12][12],根据输入的要求 //求出二维数组的左方区域元素的平均值或元素的和 //数组的2条对角线将数组分为上下左右四个部分 //黄色部分为对角线,绿色部分为左方区域 //第一行输入一个大写字母,若为's',则表示需要求出左方部分的元素的和 //若为'm',则表示需要求出左方部分的元素的平均值 //接下来12行,每行包含12个用空格隔开的浮点数,表示这个二维数组 //其中,第 i+1 行的第 j+1 列表示数组元素m[i][j] //输出一个数,表示所求的平均数或元素的和的值,保留1位小数 int main() { char t; cin >> t; double m[12][12]; int i, j; for ( i = 0; i < 12; i++) { for ( j = 0; j < 12; j++) { cin >> m[i][j]; } } double sum = 0; int num = 0; for ( i = 1; i <= 5; i++) { for (j = 0; j <= i - 1; j++) { sum += m[i][j]; num++; } } for (i = 6; i <= 10; i++) { for (j = 0; j <= 10 - i; j++) { sum += m[i][j]; num++; } } if (t == 's') printf("%.1lf\n", sum); else printf("%.1lf\n", sum / num); return 0; }
第2题  平方矩阵 I

比如:

emmm,这道题,肯定不想让我们直接使用printf输出。我们需要寻找规律

举个例子呗~

因此,本道题的代码如下:(注意:取最小值时,需要引用头文件#include<math.h>)

//平方矩阵 I //输入整数n,输出一个n阶的回字形二维数组 //数组的最外层位1,次外层为2,以此类推 //输入包含多行,每行包含1个整数n //当输入行为n=0时,表示输入结束,且该行无需做任何处理 //对于每个输入整数n,输出一个满足要求的n阶二维数组 //每个整数占n行,每行包含n个用空格隔开的整数 //每个数组输出完毕后,输出一个空行 int main() { int n; while (cin >> n, n) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { int up = i, down = n - i + 1, left = j, right = n - j + 1; cout << min(min(up, down), min(left, right)) << " "; } cout << endl; } } return 0; }
第3题  数组变换

   哈哈~这道题,先来一个小学生都看得懂的方法:

//数组变换 //输入一个长度为20的整数数组n //将整个数组翻转,使得第一个元素成为倒数第一个元素 //第二个元素成为倒数第二个元素,...,倒数第二个元素成为第二个元素 //倒数第一个元素成为第一个元素,输出翻转后的数组 //输入包含20个整数,每个数占一行 //输出新数组中的所有元素,每个元素占一行 //输出格式为"N[i]=x",其中i为元素编号(从0开始),x为元素的值 int main() { int n[20]; int b[20]; int i, j; for (i = 0; i < 20; i++) //往原数组中添加元素 { cin >> n[i]; } for (i = 19, j = 0; i >= 0; i--, j++) //将原数组里面的元素拷贝到新数组中 { b[j] = n[i]; } for (i = 0; i < 20; i++) //输出新数组里面的元素 { printf("N[%d] = %d\n", i, b[i]); } return 0; }

我们还可以采用另外一种方法,其中就是旋转数组的最初版本。定义reverse函数,用双指针法交换首尾元素,当它们相遇或错过时,循环结束。

代码如下:

void Reverse(int a[], int left,int right) { while (left < right) { int temp = a[left]; a[left] = a[right]; a[right] = temp; left++; right--; } } int main() { int n[20]; int i; for (i = 0; i < 20; i++) { cin >> n[i]; } Reverse(n, 0, 19); for (i = 0; i < 20; i++) { printf("N[%d] = %d\n", i, n[i]); } cout << endl; return 0; }
第4题  斐波那契数列

斐波那契数列,是我们的老朋友啦!之前的习题中,见过很多次。今天再来认识一下~

f(0) = 0,f(1)=1,

f(2) = f(0) + f(1) = 1

f(3) = f(1) + f(2) = 2

f(4) = f(2) + f(3) = 3

f(5) = f(3) + f(4) = 5

......

f(n) = f(n-2) + f(n-1)

可以看出,从第2项开始,每一项 = 前2项之和

这道题,是想让我们求斐波那契数列的第n项,但是不止输出1次,而是输出t次(t表示实验次数)

这就需要我们事先把斐波那契数组准备好,将数字填进数组。再根据输入的第n项,输出Fib(n),这样循环t次。

代码如下:

//斐波那契数列 //输入整数n,求出斐波那契数列中的第n项是多少 //斐波那契数列的第0项是0,第1项是1 //从第2项开始的每一项都等于前2项之和 //输入第一行包含整数t,表示共有t个测试数据 //接下来的t行,每行包含一个整数n //每个测试数据输出一个结果,每个结果占一行 //结果格式为"Fib(n)=x",其中,n为项数,x为第n项的值 int main() { int t; //表示共有t个测试数据 cin >> t; int n; //求出斐波那契数列中的第n项是多少 long long Fib[60];//数组的元素类型必须是long long //如果为int,元素会超过int类型的范围,导致溢出 Fib[0] = 0; Fib[1] = 1; for (int i = 2; i < 60; i++) { Fib[i] = Fib[i - 1] + Fib[i - 2]; } while (t--) { cin >> n; printf("Fib(%d) = %lld\n", n, Fib[n]); } return 0; }

在这里,注意:二维数组Fib的元素类型必须为long long。如果为int类型,元素可能会超过int类型的范围,导致溢出。


第5题  最小数和它的位置

这道题,我们可以使用擂台法。将第一个元素保存到临时变量里面,后面的元素依次进行比较,如果后面的某一个元素比第一个元素小,则更新最小数的值以及位置

代码如下:

//最小数和它的位置 //输入一个整数n和一个长度为n的整数数组x //请你找出数组中最小的元素,并输出它的值和下标 //注意: 如果有多个最小值,则返回下标最小的那个 //输入第一行包含整数n //第二行包含n个用空格隔开的整数x[i] //第一行输出"Minimum value: x",其中x为数组元素最小值 //第二行输出"Position: y",其中y为最小值元素的下标(下标从0开始计数) int main() { int n; cin >> n; int a[1001]; int i; for (i = 0; i < n; i++) { cin >> a[i]; } int min = a[0]; int min_i = 0; for (i = 1; i < n; i++) { if (a[i] < min) { min = a[i]; min_i = i; } } printf("Minimum value: %d\n", min); printf("Position: %d\n", min_i); return 0; }
第6题  数组中的列

求某一列的元素的平均值或元素的和,那么列不变,行数从 0~11依次相加。

代码如下:

//数组中的列 //输入一个二维数组m[12][12],根据输入的要求 //求出二维数组中某一列的元素的平均值或元素的和 //第一行输入整数c,表示所求的具体列数(列数从0开始计数) //第二行包含1个字母,若为's',则表示需要求出第c列的元素的和 //若为'm',则表示需要求出第c列的元素的平均值 //接下来的12行,每行包含12个用空格隔开的浮点数,表示这个二维数组 //其中第 i+1 行的第 j+1 个数表示数组元素m[i][j] //输出1个数,表示所求的平均数或元素的和的值,保留一位小数 int main() { int c; //表示所求的具体列数(列数从0开始计数) cin >> c; char t; cin >> t; double m[12][12]; for (int i = 0; i < 12; i++) { for (int j = 0; j < 12; j++) { cin >> m[i][j]; } } double sum = 0; int num = 0; for (int i = 0; i < 12; i++) { sum += m[i][c]; num++; } if (t == 's') printf("sum = %.1lf\n", sum); else printf("average = %.1lf\n", sum / num); return 0; }
第7题  数组的右下半部分

这道题,其实是寻找行数和列数的规律

ij111210~1139~1148~1157~1166~1175~1184~1193~11102~11111~11i12-i ~ 11

因此,行数和列数的规律:行数的取值范围1~11,列数的起始位置为12-i,结束位置为11

代码如下:

//数组的右下半部分 //输入一个二维数组m[12][12] //求二维数组的右下半部分元素的平均值或元素的和 //右下半部分部分指对角线下方的部分 //第一行输入一个大写字母,若为's',则表示需要求出右下半部分的元素的和 //若为'm',则表示需求出右下半部分的元素的平均值 //接下来12行,每行包含12个用空格隔开的浮点数,表示这个二维数组 //其中第i+1行的第j+1个数表示数组元素m[i][j] //输出1个数,表示所求的平均数或和的值,保留1位小数 int main() { char t; cin >> t; double m[12][12]; int i, j; for (i = 0; i < 12; i++) { for (j = 0; j < 12; j++) { cin >> m[i][j]; } } double sum = 0; int num = 0; for (i = 1; i <= 11; i++) { for (j = 12 - i; j <= 11; j++) { sum += m[i][j]; num++; } } if (t == 's') printf("sum = %.1lf\n", sum); else printf("average = %.1lf\n", sum / num); return 0; }
第8题  数组的左下半部分

这道题,同样是寻找行数和列数的关系

ij1020~130~240~350~460~570~680~790~8100~9110~10i0 ~ i-1

因此,行数和列数的规律:行数的取值范围1~11,列数的起始位置为0,结束位置在i-1

代码如下:

//数组的左下半部分 //输入一个二维数组m[12][12] //求二维数组的左下半部分元素的平均值或元素的和 //左下半部分部分指对角线下方的部分 //第一行输入一个大写字母,若为's',则表示需要求出左下半部分的元素的和 //若为'm',则表示需求出左下半部分的元素的平均值 //接下来12行,每行包含12个用空格隔开的浮点数,表示这个二维数组 //其中第i+1行的第j+1个数表示数组元素m[i][j] //输出1个数,表示所求的平均数或和的值,保留1位小数 int main() { char t; cin >> t; double m[12][12]; int i, j; for (i = 0; i < 12; i++) { for (j = 0; j < 12; j++) { cin >> m[i][j]; } } double sum = 0; int num = 0; for (i = 1; i <= 11; i++) { for (j = 0; j <= i - 1; j++) { sum += m[i][j]; num++; } } if (t == 's') printf("sum = %.1lf\n", sum); else printf("ave = %.1lf\n", sum / num); return 0; }
第9题  数组的下方区域

这道题,同样是寻找行数和列数的规律:

ij75~684~793~8102~9111~10i12-i ~ i-1

 通过表格,我们发现行数的取值范围:7~11,列数的起始位置:12-i,结束位置:i-1

代码如下:

//数组的下方区域 //输入一个二维数组m[12][12] //求二维数组的下方部分元素的平均值或元素的和 //下方部分部分指对角线下方的部分 //第一行输入一个大写字母,若为's',则表示需要求出下方部分的元素的和 //若为'm',则表示需求出下方部分的元素的平均值 //接下来12行,每行包含12个用空格隔开的浮点数,表示这个二维数组 //其中第i+1行的第j+1个数表示数组元素m[i][j] //输出1个数,表示所求的平均数或和的值,保留1位小数 int main() { char t; cin >> t; double m[12][12]; int i, j; for (i = 0; i < 12; i++) { for (j = 0; j < 12; j++) { cin >> m[i][j]; } } double sum = 0; int num = 0; for (i = 7; i <= 11; i++) { for (j = 12 - i; j <= i - 1; j++) { sum += m[i][j]; num++; } } if (t == 's') printf("sum = %.1lf\n", sum); else printf("ave = %.1lf\n", sum / num); return 0; }
第10题  数组的右方区域

这道题,同样是寻找行数和列数的规律,我们可以把阴影部分分成上下2块区域

右方区域---上方部分 ij111210~1139~114

8~11

57~11i12-i ~ 11

 上面是上方部分行数和列数之间的关系,接下来我们看看下方部分:

右方区域---下方部分 ij67~1178~1189~11910~111011ii+1 ~ 11

通过表格,我们可以发现:上方部分:行数的取值范围:1~5,列数的起始位置:12-i,结束位置:11;下方部分:行数的取值范围:6~10,列数的起始位置:i+1,结束位置:11

代码如下:

//数组的右方区域 //输入一个二维数组m[12][12] //求二维数组的右方部分元素的平均值或元素的和 //右方部分部分指对角线右方的部分 //第一行输入一个大写字母,若为's',则表示需要求出右方部分的元素的和 //若为'm',则表示需求出右方部分的元素的平均值 //接下来12行,每行包含12个用空格隔开的浮点数,表示这个二维数组 //其中第i+1行的第j+1个数表示数组元素m[i][j] //输出1个数,表示所求的平均数或和的值,保留1位小数 int main() { char t; cin >> t; double m[12][12]; int i, j; for (i = 0; i < 12; i++) { for (j = 0; j < 12; j++) { cin >> m[i][j]; } } //右方区域 //上 double sum = 0; int num = 0; for (i = 1; i <= 5; i++) { for (j = 12 - i; j <= 11; j++) { sum += m[i][j]; num++; } } //下 for (i = 6; i <= 10; i++) { for (j = i + 1; j <= 11; j++) { sum += m[i][j]; num++; } } if (t == 's') printf("sum = %.1lf\n", sum); else printf("ave = %.1lf\n", sum / num); return 0; }
第11题  平方矩阵Ⅱ

 我们一起来看看例子吧~

乍一看,好像看不出来有啥规律,咋整?

嘿嘿,我们单独拿一个例子出来,你就明白了

因此,本道题的代码如下:

//平方矩阵Ⅱ //输入整数n,输出一个n阶的二维数组 //数组的形式参照样例 //输入包含多行,每行包含一个整数n //当输入行为 n=0 时,表示输入结束,且该行无需作任何处理 //对于每个输入整数n,输出一个满足要求的n阶二维数组 //每个数组占n行,每行包含n个用空格隔开的整数 //每个数组输出完毕后,输出一个空行 int main() { int n; int a[60][60]; while (cin >> n, n) { for (int i = 0; i < n; i++) { a[i][i] = 1; //右对角线上的元素全为"1" for (int j = i + 1, k = 2; j < n; j++, k++) a[i][j] = k; //纵向 for (int m = i + 1, k = 2; m < n; m++, k++) a[m][i] = k; //横向 } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << a[i][j] << " "; } cout << endl; } } return 0; }
第12题  平方矩阵Ⅲ

这道题,题目已经告诉了我们规律:M[i][j] = ,相当于是2的n次方的变形版。本道题不难,代码如下:

//平方矩阵Ⅲ //输入整数n,输出一个n阶的二维数组 //这个n阶二维数组满足m[i][j] = 2^(i+j) //输入包含多行,每行包含一个整数n //当输入行为 n=0 时,表示输入结束,且该行无需作任何处理 //对于每个输入整数n,输出一个满足要求的n阶二维数组 //每个数组占n行,每行包含n个用空格隔开的整数 //每个数组输出完毕后,输出一个空行 int main() { int n; int m[60][60]; while (cin >> n, n) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { m[i][j] = 1;//数组中的元素必须先初始化为1 for (int h = 0; h < i + j; h++) m[i][j] *= 2; cout << m[i][j] << " "; } cout << endl; } } return 0; }

 或者,咱们不创建二维数组,直接打印,节省空间:

int main() { int n; while (cin >> n, n) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { int v = 1; for (int h = 0; h < i + j; h++) v *= 2; cout << v << " "; } cout << endl; } } return 0; }

亦或者,咱们可以直接调用库里面的pow函数。需要引用头文件#include<math.h>

int main() { int n; int m[60][60]; while (cin >> n, n) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { m[i][j] = pow(2, i + j); //调用库函数pow } } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << m[i][j] << " "; } cout << endl; } } return 0; }
第13题  蛇形矩阵

emmm,光看题目,不好理解,咱们一起画画图~

因此,我们可以分别定义2个数组,存放横坐标的变化和纵坐标的变化,记为dx和dy。定义变量d,指向dx和dy数组的初始位置(下标为0)。如果出现"撞墙"这种情况,我们应该让d指向dx和dy数组的下一个位置,这样才能变换方向。

代码如下:

//蛇形矩阵 //输入2个整数n和m,输出一个n行m列的矩阵 //将数字1到n*m按照回字蛇形填充至矩阵中 //输入共一行,包含2个整数n和m //输出满足要求的矩阵 //矩阵占n行,每行包含m个空格隔开的整数 int h[100][100] = {0};//初始时,h的所有元素都被初始化为0 int main() { int n, m; cin >> n >> m; int dx[] = { 0,1,0,-1 }; //横坐标的变化 int dy[] = { 1,0,-1,0 }; //纵坐标的变化 int x,y; int k; int d; for (x = 0, y = 0,d = 0, k = 1; k <= n * m; k++) { h[x][y] = k; int a = x + dx[d]; //把新的横坐标存放到a里面 int b = y + dy[d]; //把新的纵坐标存放到b里面 //越界和重复 //如果h[a][b]的值不等于0,说明该位置已经被填充过数字,即发生了重复 if (a < 0 || a >= n || b < 0 || b>=m || h[a][b]) { d = (d + 1) % 4; //更新d指向的位置 a = x + dx[d]; b = y + dy[d]; } x = a; //将a的值赋给x y = b; //将b的值赋给y } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cout << h[i][j] << " "; } cout << endl; } return 0; }

通过代码,我们知道:

h是一个二维数组,用于存储蛇形矩阵的值。初始时,h的所有元素都被初始化为0。

当某个位置(x,y)被填充后,h[x][y]的值会被设置为当前的数字k。因此,如果h[a][b]的值不为0,说明该位置已经被填充过数字,即发生了重复。


片尾

今天我们学习了C++蓝桥杯基础篇(六),讲解了数组的相关习题。下一篇,我们将介绍字符串,希望对大家有帮助!!!

求点赞收藏加关注!!!

谢谢大家!!!

标签:

C++蓝桥杯基础篇(六)由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“C++蓝桥杯基础篇(六)