开灯问题

任务描述

本关任务:有 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;
}