片頭
嗨~小伙伴們,大家好!今天我們來一起學習藍橋杯基礎篇(六),練習相關的數組習題,準備好了嗎?咱們開始咯!
第1題??數組的左方區域
這道題,實質上是找規律,我們觀察到,可以將綠色的區域分成上下2個部分,因此,我們可以列出2張表。
i | j |
1 | 0 |
2 | 0~1 |
3 | 0~2 |
4 | 0~3 |
5 | 0~4 |
i | 0 ~ i-1 |
再看另一張表
i | j |
6 | 0~4 |
7 | 0~3 |
8 | 0~2 |
9 | 0~1 |
10 | 0 |
i | 0 ~ 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題??數組的右下半部分
這道題,其實是尋找行數和列數的規律
i | j |
1 | 11 |
2 | 10~11 |
3 | 9~11 |
4 | 8~11 |
5 | 7~11 |
6 | 6~11 |
7 | 5~11 |
8 | 4~11 |
9 | 3~11 |
10 | 2~11 |
11 | 1~11 |
i | 12-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題??數組的左下半部分
這道題,同樣是尋找行數和列數的關系
i | j |
1 | 0 |
2 | 0~1 |
3 | 0~2 |
4 | 0~3 |
5 | 0~4 |
6 | 0~5 |
7 | 0~6 |
8 | 0~7 |
9 | 0~8 |
10 | 0~9 |
11 | 0~10 |
i | 0 ~ 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題??數組的下方區域
這道題,同樣是尋找行數和列數的規律:
i | j |
7 | 5~6 |
8 | 4~7 |
9 | 3~8 |
10 | 2~9 |
11 | 1~10 |
i | 12-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塊區域
i | j |
1 | 11 |
2 | 10~11 |
3 | 9~11 |
4 | 8~11 |
5 | 7~11 |
i | 12-i ~ 11 |
?上面是上方部分行數和列數之間的關系,接下來我們看看下方部分:
i | j |
6 | 7~11 |
7 | 8~11 |
8 | 9~11 |
9 | 10~11 |
10 | 11 |
i | i+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;//數組中的元素必須先初始化為1for (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的所有元素都被初始化為0int 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的值賦給xy = 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++藍橋杯基礎篇(六),講解了數組的相關習題。下一篇,我們將介紹字符串,希望對大家有幫助!!!
求點贊收藏加關注!!!
謝謝大家!!!