上机实验:数组(上)
开灯问题
任务描述
本关任务:有 n 盏灯,编号为 1~n。第 1 个人把所有灯打开,第 2 个人按下所有编号为 2 的倍数的开关(这些灯将被关掉),第 3 个人按下所有编号为 3 的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依次类推。一共有 k 个人,问最后有哪些灯开着?编写一个程序,输入 n 和 k,输出开着的灯的编号(k≤n≤1000)。
程序运行示例: 输入:7 3 输出:1 5 6 7
测试说明
测试输入 1:
输入:8 4 输出:1 4 5 6 7 8
参考代码
#include <iostream>
using namespace std;
int main(void) {
/** Begin **/
int n, k, lamp[1010];
cin >> n >> k;
for (int i=1;i<=n;i++) lamp[i] = 0;
for (int i=1;i<=k;i++) {
for (int j=i;j<=n;j+=i) lamp[j] = !lamp[j];
}
for (int i=1;i<=n;i++) if (lamp[i])
cout << i << " ";
/** End **/
return 0;
}
删除重复数据(单数组版)
任务描述
本关任务:编写一个能删除数组中重复数据的程序。
编程要求
根据提示,在右侧编辑器补充代码,输入一组数据,删除掉其中的重复数据,输出数组中元素个数(假设为n个)并按照原顺序输出所有数字的首次出现。
注意:不引入第二个数组;输出数组中元素时,不再进行新的判断,只能用for(int k=0; k<n; k++) cout<<arr[k]形式
保证输入长度不超过100,保证输入的数字均为非负整数且不超过100。
测试说明
平台会对你编写的代码进行测试:
测试输入:1 2 3 1 2 3;
预期输出:
1 2 3
参考代码
#include <iostream>
using namespace std;
int main(void) {
/** Begin **/
int n = 0, arr[101];
for (; cin>>arr[n]; n++) {
for (int j=0;j<n;j++) if (arr[j] == arr[n]) {
n--;
break;
}
}
for (int k=0; k<n; k++) cout << arr[k] << " ";
/** End **/
return 0;
}
回文数
任务描述
本关任务:回文数是指从左向右念和从右向左念都一样的数。如 12321 就是一个典型的回文数。给定一个进制 B(2≤B≤20,由十进制表示),求出所有的大于等于 1 小于等于 200(十进制下)且它的平方用 B 进制表示是回文数的数。用“A”,“B”,“C”…表示 10,11,12 等等。
编写一个程序,输入整数 B(B 由十进制表示),输出分成多行,每行输出两个 B 进制的数字,第二个数是第一个数的平方,且第二个数是回文数。
程序运行示例:
输入:8 输出:
1 1
2 4
3 11
6 44
11 121
13 171
33 1331
101 10201
111 12321
117 14141
121 14641
123 15351
303 112211
参考代码
#include <iostream>
using namespace std;
int main(void) {
/** Begin **/
int B;
cin >> B;
for (int i=1;i<=200;i++) {
int arr[25] = {0}, arr2[25] = {0}, is_palin = 1;
for (int _i=i*i;_i;_i/=B) arr[++arr[0]] = _i%B;
for (int i=1, j=arr[0]; i<j; i++, j--)
if (arr[i] != arr[j]) is_palin = 0;
if (is_palin) {
for (int _i=i;_i;_i/=B) arr2[++arr2[0]] = _i%B;
for (int j=arr2[0];j>=1;j--) {
char tmp = arr2[j]<10?arr2[j]+'0':arr2[j]-10+'A';
cout << tmp;
}
cout << " ";
for (int j=arr[0];j>=1;j--) {
char tmp = arr[j]<10?arr[j]+'0':arr[j]-10+'A';
cout << tmp;
}
cout << "\n";
}
}
/** End **/
return 0;
}
数字金字塔-二维数组
任务描述
本关任务:观察下面的数字金字塔,寻找一个算法查找从最高点到底部任意处结束的路径,使路径经过的数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
7
3 8
8 1 1
2 7 4 4
4 5 2 6 5
在上面的例子中,从 7 到 3 到 8 到 7 到 5 的路径产生了最大的数字和。
编写一个程序,首先输入数字金字塔层次数R(1≤R≤10),接着后面的每行为这个数字金字塔特定层包含的整数(所有整数大于等于0且小于100),输出计算出来的最大的和。
提示:设置一个两维数组 f,f[i,j] 表示从最高点(最高点为第 1 层)到达第 i 层第 j 个位置时经过路径数字的最大和,则 f[i+1,j]+=Max{ f[i,j-1],f[i,j]}(1≤i≤r-1,1≤j≤i)。请注意边界值的处理,f[i,0]=0。
程序运行示例: 输入:
5
7
3 8
8 1 1
2 7 4 4
4 5 2 6 5
输出:30
参考代码
#include <iostream>
using namespace std;
int f[11][11];
int main(void) {
/** Begin **/
int r;
cin >> r;
int mx = 0;
for (int i=1;i<=r;i++) {
for (int j=1;j<=i;j++) {
cin >> f[i][j];
if (f[i-1][j]>f[i-1][j-1])
f[i][j] += f[i-1][j];
else
f[i][j] += f[i-1][j-1];
if (f[i][j] > mx) mx = f[i][j];
}
}
cout << mx << endl;
/** End **/
return 0;
}