《C++编程这样学》第七章:一维数组- 加油站题解

1. 陶陶摘苹果

题目链接:http://csp.magu.ltd/problem/J0760

【问题描述】

陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。

现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。

【题解代码】
#include <iostream>
using namespace std;

int a[15];

int main()
{
    
    for (int i = 0; i < 10; i++)
    {
        cin >> a[i];
    }
    int h;
    cin >> h;
    int cnt = 0;
    for (int i = 0; i < 10; i++)
    {
        if (h + 30 >= a[i])
            cnt++;
    }
    cout << cnt << endl;
    return 0;
}

2.数组相乘

题目链接:http://csp.magu.ltd/problem/J0761

【问题描述】

小明突发奇想,发明了数组相乘的运算,参与相乘运算的所有数组的元素都是整型数,并且所有数组需要有相同的元素个数,数组相乘后的结果为所有数组相应位置上的元素的乘积之和。

例如,数组 a[3]={2,4,6},b[3]={3,6,9},则数组 a ∗ b a\ast b ab 的结果为 2 ∗ 3 + 4 ∗ 6 + 6 ∗ 9 = 34 2\ast 3+4\ast6+6\ast9=34 23+46+69=34

再如,数组a[3]={2,4,6},b[3]={3,6,9},c[3]={1,2,3},则数组 a ∗ b ∗ c a\ast b \ast c abc 的结果为 2 ∗ 3 ∗ 1 + 4 ∗ 6 ∗ 2 + 6 ∗ 9 ∗ 3 = 216 2\ast3\ast1 + 4\ast6\ast2 + 6\ast9\ast3=216 231+462+693=216

编写程序,输入n个元素个数均为m的数组,按照“数组相乘”的规则,计算n个数组相乘的结果。

【题解代码】
#include <iostream>
using namespace std;

int a[15];

int main()
{
    int n, m;
    cin >> n >> m;
    int ans = 0;
    bool flag = 1;
    while (n--)
    {
        if (flag)
        {
            flag = 0;
            for (int i = 0; i < m; i++)
            {
                cin >> a[i];
            }
        }
        else
        {
            for (int i = 0; i < m; i++)
            {
                int x;
                cin >> x;
                a[i] *= x;
            }
        }
    }
    for (int i = 0; i < m; i++)
        ans += a[i];
    cout << ans;
    return 0;
}

3.整数的裂变

题目链接:http://csp.magu.ltd/problem/J0762

【问题描述】

阿尔法星球上,任意一个数都可以裂变为单个数字,裂变后的数字可以重组为新的整数,而裂变量的定义就是重组后的最大数与最小数之间的差。例如,237可以裂变为数字2 3 7,重组后可以得到237、273、327、372、723、732六个数,裂变量为732-237=495。

【题解代码】
#include <iostream>
using namespace std;

int a[15];

int main()
{
    long long n;
    cin >> n;
    int idx = 1; 
    while (n)
    {
        int t = n % 10;
        n /= 10;
        a[idx++] = t;
    }
    
    for (int i = 1; i < idx - 1; i++)
    {
        bool f = 1;
        for (int j = 1; j < idx - i; j++)
        {
            if (a[j] > a[j + 1])
            {
                f = 0;
                swap(a[j], a[j + 1]);
            }
        }
        if (f)
            break;
    }
    long long minn = 0, maxx = 0;
    for (int i = 1; i < idx; i++)
        minn = minn * 10 + a[i];
    for (int i = idx - 1; i >= 1; i--)
        maxx = maxx * 10 + a[i];
    cout << maxx - minn << endl;
    return 0;
}

4.约瑟夫问题

题目链接:http://csp.magu.ltd/problem/J0763

【问题描述】

约瑟夫问题又称为约瑟夫环、丢手绢问题或猴子选大王问题。即,编号分别为1~n的 n个人围成一圈,第一个人的编号为 1,最后一个人的编号为n,由第一个人从1开始报数,报数为m的人出列,再由下一个人重新从1开始报数,报数为m的人再出列,以此类推,直到所有的人都出列,编写程序按出列顺序输出出列人的编号。

【题解代码】
#include <iostream>
using namespace std;

int ne[110];

int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i < n; i++)
        ne[i] = i + 1;
    ne[n] = 1;
    int cnt = 0, i = 0, p = n;
    while (cnt < n)
    {
        while (++i < m)
        {
            p = ne[p];
        }
        cout << ne[p] << " ";
        cnt++;
        ne[p] = ne[ne[p]];
        i = 0;
    }
    return 0;
}

5.电影喜好调研

题目链接:http://csp.magu.ltd/problem/J0764

【问题描述】

某一年,院线总共上映了300部电影,各电影的编号分别为1~300,现在对n个参与调研的人的反馈进行统计分析,这n个人中的每个人都有各自喜欢的电影,每个人反馈自己喜欢的电影编号,每个人可以反馈多部喜欢的电影。编写程序,统计有多少部电影是参与调研的人都喜欢的,按由小到大输出电影编号。

【题解代码】
#include <iostream>
using namespace std;

int a[310];

int main()
{
    int n, m;
    cin >> n;
    m = n;
    while (n--)
    {
        int x;
        while (cin >> x, x) // 寰幆杈撳叆x锛屼笖x!=0
        {
            a[x]++;
        }
    }
    bool f = 0;
    for (int i = 1; i <= 300; i++)
    {

        if (a[i] == m)
        {
            cout << i << " ";
            f = 1;
        }
    }
    if (f == 0)
        cout << 0;
    return 0;
}

6.第k名的成绩

题目链接:http://csp.magu.ltd/problem/J0765

【问题描述】

在一次考试中,每个学生的成绩都不相同,现知道了n个学生的成绩,编写程序求考第k名的学生的成绩。

【题解代码】
#include <iostream>
using namespace std;

double a[110];

int main()
{
    int n, k;
    cin >> n >> k;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < n - 1; i++)
    {
        bool f = true;
        for (int j = 0; j < n - i; j++)
        {
            if (a[j] < a[j + 1])
            {
                swap(a[j], a[j + 1]);
                f = false;
            }
        }
        if (f)
            break;
    }
    printf("%.1f", a[k - 1]);
    return 0;
}

7.序列去重2

题目链接:http://csp.magu.ltd/problem/J0766

【问题描述】

编写程序,输入含有n个整数的序列,对这个数列进行去重操作。所谓去重,是指对这个序列中每个重复出现的数,只在该数第一次出现的位置保留该数,删除序列中其余与它相同的数。

【题解代码】
#include <iostream> 
using namespace std;

int a[110]; // [10,100] 

int main()
{
	int n;
	cin >> n;
	while (n --)
	{
		int x;
		cin >> x;
		if (a[x] == 0) {
			cout << x << " ";
			a[x] = 1;  
		}
	} 
	return 0;
}

8.右移k位

题目链接:http://csp.magu.ltd/problem/J0767

【问题描述】

编写程序,输入含有n个整数的序列,将序列中数的位置右移k位数后再输出。右移k位的规则如下:

  • 如数组有5个元素,k为3,则下标为0的元素移到下标为3的位置
  • 下标为1的元素移到下标为4的位置,下标为2的元素移到下标为0的位置
  • 下标为3的元素移到下标为1的位置,下标为4的元素移到下标为2的位置,以此类推。
【题解代码】
#include <iostream>
using namespace std;

int a[110], b[110];

int main()
{
    int n, k;
    cin >> n >> k;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    k %= n;
    for (int i = 0; i < n; i++)
    {
        cout << a[(i + n - k) % n] << " ";
    }
    return 0;
}

9.明明的随机数

题目链接:http://csp.magu.ltd/problem/J0768

【问题描述】

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数( N ⩽ 100 N\leqslant100 N100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

【题解代码】
#include <iostream>
using namespace std;

const int N = 1010;
int st[N], a[N];
int main()
{
    int n;
    cin >> n;
    int x, idx = 0;

    for (int i = 0; i < n; i++)
    {
        cin >> x;
        if (!st[x])
        {
            a[idx++] = x;
            st[x] = 1;
        }
    }
    
    for (int i = 0; i < idx - 1; i++)
    {
        bool f = true;
        for (int j = 0; j < idx - i; j++)
        {
            if (a[j] > a[j + 1])
            {
                f = false;
                swap(a[j], a[j + 1]);
            }
        }
        if (f)
            break;
    }
    cout << idx << endl;
    for (int i = 0; i < idx; i++)
    {
        cout << a[i] << " ";
    }
    return 0;
}

10.最长平台

题目链接:http://csp.magu.ltd/problem/J0769

【问题描述】

已知一个从小到大排序的数组,这个数组的一个平台(Plateau)就是连续的一串值相同的元素,并且这一串元素不能再延伸。例如,对于数组1,2,2,3,3,3,4,5,5,612-23-3-345-56都是该数组的平台。编写程序,输入一个数组,输出这个数组最长平台的长度。在上面的例子中3-3-3就是最长的平台。

【题解代码】
#include <iostream>
using namespace std;

int a[1010];

int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i ++) cin >> a[i];
	
	int ans = -1, len = 1;
	for (int i = 1; i < n; i ++) {
		if (a[i] == a[i+1]) len ++;
		else {
			ans = max(ans, len);
			len = 1;
		}
	}
	ans = max(ans, len);
	cout << ans << endl;
	return 0;
}

11.图书管理员问题

题目链接:http://csp.magu.ltd/problem/J0770

【问题描述】

图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个正整数。

每位借书的读者手中有一个需求码,这个需求码也是一个正整数。如果一本书的图书编码恰好以读者的需求码结尾,那么这本书就是这位读者所需要的。

小 D 刚刚当上图书馆的管理员,她知道图书馆里所有书的图书编码,她请你帮她写一个程序,对于每一位读者,求出他所需要的书中图书编码最小的那本书,如果没有他需要的书,请输出-1。

【题解代码】
#include <iostream>
#include <cmath>     // pow sqrt
#include <algorithm> // sort
using namespace std;

int a[1100];

int main()
{
    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    sort(a + 1, a + n + 1);
    while (q--)
    {
        int len, id;
        cin >> len >> id;
        int m = pow(10, len); // 10^len 娉ㄦ剰pow鐨勬暟鎹被鍨嬫槸double
        bool f = false;
        for (int i = 1; i <= n; i++)
        {
            if (a[i] % m == id)
            {
                f = true;
                cout << a[i] << endl;
                break;
            }
        }
        if (!f)
            cout << "-1" << endl;
    }

    return 0;
}

12.校门外的数

题目链接:http://csp.magu.ltd/problem/J0771

【问题描述】

某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。

由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起点和终点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。

编写程序计算将这些树都移走后,马路上还有多少棵树。

【题解代码】
#include <iostream>
using namespace std;

int tree[10010];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0; i <= n; i ++) tree[i] = 1;
	while (m --)
	{
		int l, r;
		cin >> l >> r;
		for (int i = l; i <= r; i ++) {
			tree[i] = 0;
		}
	}
	int cnt = 0;
	for (int i = 0; i <= n; i ++) {
		if (tree[i] == 1) cnt ++;
	}
	cout << cnt << endl;
	return 0;
}

13.有趣的跳跃

题目链接:http://csp.magu.ltd/problem/J0772

【问题描述】

对于一个含有n个整数的序列,如果相邻元素的差的绝对值经过排序后正好是从1到 n-1,就称这个序列存在有趣的跳跃。

例如,序列1,4,2,3存在有趣的跳跃,因为它的相邻元素差的绝对值分别为3,2,1,排序后是1,2,3。当然,任何只包含单个元素的序列一定存在有趣的跳跃。

编写程序,判定一个给定的序列是否存在有趣的跳跃。

【题解代码】
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int a[3010], b[3010];

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];

    for (int i = 1; i < n; i++)
    {
        b[i] = abs(a[i] - a[i - 1]); 
    }
    sort(b + 1, b + n);
    bool f = true;
    for (int i = 1; i < n; i++)
    {
        if (b[i] != i)
        {
            f = false;
            break; 
        }
    }
    if (f)
        cout << "Jolly" << endl;
    else
        cout << "Not Jolly" << endl;
    return 0;
}
  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值