C++set集合与并查集map映射,哈希表应用实例B3632 集合运算 1P1918 保龄球

集合的性质

  • 无序性
  • 互异性
  • 确定性

B3632 集合运算 1

题面

题目背景

集合是数学中的一个概念,用通俗的话来讲就是:一大堆数在一起就构成了集合。

集合有如下的特性:

  • 无序性:任一个集合中,每个元素的地位都是相同的,元素之间是无序的。

  • 互异性:一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次。

  • 确定性:给定一个集合,任给一个元素,该元素或者属于或者不属于该集合,二者必居其一,不允许有模棱两可的情况出现。

元素 a 属于集合 A 记作 a∈A,反之则记作 a∈/A。

若一个集合中不存在任何元素,则称该集合为空集,记作 ∅。空集是所有集合的子集。

一个集合内的元素个数称为该集合的大小。A 集合的大小可记作 ∣A∣。

集合 C 是集合 A 与 B 的交集,当且仅当对于任何元素 a∈C,有 a∈A 且 a∈B,并且对于任何元素 b∈/C,有 b∈/A 或 b∈/B。记作 A∩B。

简单地说,交集是由所有同时属于两个集合的元素所构成的,就像两个集合相交;而并集是由所有属于其中任意一个集合的元素所构成的,就像两个集合合并。

特别地,对于形如 {x∣a≤x≤b} 的集合,可以记作 [a,b]。其中,如果左侧符号改为小于号,则左侧中括号改为小括号。右侧同理。

题目描述

现在给予两个集合 A 和 B,均由 00 到 6363 之间的整数组成。

请依次求出:

  • ∣A∣
  • A∩B
  • A∪B

输入格式

输入四行。

第一行一个整数 x(0≤x≤63),表示集合 A 的元素个数。

第二行 x 个整数 a1​,...ax​,表示集合 A 的各个元素,保证不重复。如果 A 是空集,则这一行没有数字。

第三行一个整数  y(0≤y≤63),表示集合 B 的元素个数。

第四行 y 个整数 b1​,...bx​,表示集合 B 的各个元素,保证不重复。如果 B 是空集,则这一行没有数字。

输出格式

输出三行。

第一行输出一个整数,表示 ∣A∣。

第二行输出若干个整数,表示 A∩B 中对应元素,从小到大输出,用空格隔开。如果是空集,则这一行什么也不输出,保留换行。

第三行输出若干个整数,表示 A∪B 中对应元素,从小到大输出,用空格隔开。如果是空集,则这一行什么也不输出,保留换行。

输入输出样例

输入 #1

4
1 3 5 8
3
3 6 8

输出 #1

4
3 8
1 3 5 6 8

输入 #2

0

4
1 2 3 4

输出 #2

0

1 2 3 4

题解

使用set的方法有很多种,根据这道题目的要求可以做出以下输出

循环,如果读到了一个数,就将 a 数组对应的元素标记为 1

循环,如果读到了一个数,就将 b 数组对应的元素标记为 1

循环,i 从 0 到 63,输出 A 和 B 的交集

如果 i 同时在集合 A 和 B 中,说明它是 A∩B 的元素。

循环,i 从 0 到 63,输出 A 和 B 的并集

如果 i 在集合 A 或 B 至少一个集合,说明它是 A∪B 的元素。

代码

#include<iostream>
using namespace std;
int a[65], b[65], x, y, tmp;
int main() {
    // 读入 x
    cin >> x;
    for (int i = 0; i < x; i++) {
        cin >> tmp;
        a[tmp] = 1; // 将集合 A 对应的元素标记为 1
    }
    
    int sizeA = 0; // 集合 A 的大小

    // 循环,i 从 0 到 64,计算集合 A 的大小
    for (int i = 0; i < 65; i++) {
        if (a[i] == 1) {
            sizeA++;
        }
    }
    cout<<sizeA<<endl;
    // 读入 y
    cin >> y;
    for (int i = 0; i < y; i++) {
        cin >> tmp;
        b[tmp] = 1; // 将集合 B 对应的元素标记为 1
    }

    // 循环,i 从 0 到 63,输出 A 和 B 的交集
    for (int i = 0; i < 63; i++) {
        if (a[i] == 1 && b[i] == 1) {
            cout << i << " "; // 输出交集元素
        }
    }
    cout << endl;

    // 循环,i 从 0 到 63,输出 A 和 B 的并集
    for (int i = 0; i < 63; i++) {
        if (a[i] == 1 || b[i] == 1) {
            cout << i << " "; // 输出并集元素
        }
    }
    
    return 0;
}

P1918 保龄球

题面

题目描述

DL 算缘分算得很烦闷,所以常常到体育馆去打保龄球解闷。因为他保龄球已经打了几十年了,所以技术上不成问题,于是他就想玩点新花招。

DL 的视力真的很不错,竟然能够数清楚在他前方十米左右每个位置的瓶子的数量。他突然发现这是一个炫耀自己好视力的借口——他看清远方瓶子的个数后从某个位置发球,这样就能打倒一定数量的瓶子。

  1. ◯◯◯◯◯◯

  2. ◯◯◯ ◯◯◯◯ ◯

  3. ◯◯

  4. ◯ ◯◯ ◯

如上图,每个 “◯◯” 代表一个瓶子。如果 DL 想要打倒 3 个瓶子就在 1 位置发球,想要打倒 44 个瓶子就在 2 位置发球。

现在他想要打倒 m 个瓶子。他告诉你每个位置的瓶子数,请你给他一个发球位置。

输入格式

第一行包含一个正整数 n,表示位置数。

第二行包含 n 个正整数 ai​ ,表示第 i 个位置的瓶子数,保证各个位置的瓶子数不同。

第三行包含一个正整数 Q,表示 DL 发球的次数。

第四行至文件末尾,每行包含一个正整数 m,表示 DL 需要打倒 m 个瓶子。

输出格式

共 Q 行。每行包含一个整数,第 i 行的整数表示 DL 第 i 次的发球位置。若无解,则输出 0。

输入输出样例

输入 #1

5
1 2 4 3 5
2
4
7

输出 #1

3
0

题解

根据题意的程序大概逻辑:

  • 定义map 容器,名称是a,下标是int,存储int。
  • 读入n,循环。对于每个位置,读入tmpa[tmp]=i,也就是瓶子数为tmp的位置是i。
  • 读入q,循环。读入tmp,如果这个瓶子数找不到,输出0否则输出a[tmp]。

代码

#include<iostream>
#include<map>
using namespace std;
map<int,int> a; //定义 map 容器,名称是 a,下标是 int,存储 int 类型数据。

int main() {
    int n, q, tmp;
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> tmp; 
        a[tmp] = i; // 瓶子数为 tmp 的位置设置是 i。
    }
    cin >> q;
    while(q--) {
        cin>>tmp;//读入 tmp
        if(a.find(tmp)!=a.end())cout<<a[tmp]; //如果这个瓶子数可以找到(其地址非map末尾),输出 a[tmp]
        else cout<<0;//否则输出 0。
        cout<<endl;//注意输出格式!
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值