set/map作业解析

回顾一下set,map的内容:STL

P761 【入门】明明的随机数

对于一组数据完成完成"去重"与"排序"的工作。

分析

方法1:可以直接排序后去重

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 110;
int n, a[N],ans;

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i];
    sort(a, a + n);
    for (int i = 0; i < n; i++) {
        if (i == 0 || a[i] != a[i - 1])
            ans++;
    }
    cout<<ans<<endl;
    for (int i = 0; i < n; i++) {
        if (i == 0 || a[i] != a[i - 1])
            cout << a[i] << " ";
    }
    return 0;
}

方法2:利用set集合的特性,直接求入set中,再拿出来

点击查看代码
#include <bits/stdc++.h>
#include <set>
using namespace std;
typedef long long LL;

int main() {
    int n, x;
    set<int> s;
    cin >> n;
    while (n--) {
        cin >> x; s.insert(x);
    }
    cout << s.size() << endl;
    // 1. 迭代器遍历
    set<int>::iterator it = s.begin();
    for (; it != s.end(); it++)
        cout << *it << " ";
    cout << endl;
    // 2.  for each :   -std=C++11
    // for (auto u : s) cout << u << " "; cout << endl;
    // for (int u : s) cout << u << " "; cout << endl;
    return 0;
}

P760 [NOIP2007 提高组] 统计数字

某次科研调查时得到了n(1≤n≤200000)个自然数,每个数均不超过 \(1.5×10^9\),现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。

分析
自然的可以想到标记思想,定义一个数组st,st[i] 表示元素 i 出现的次数。

但是数据范围较大,无法开辟数组,于是可以转为映射,使用map完成。

点击查看代码
#include <bits/stdc++.h>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int N = 1e8 + 10;
int n, x;
map<int, int> st;

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> x; st[x]++;
    }
    // 1.iterator
    // map<int, int>::iterator it = st.begin();
    // for (; it != st.end(); it++) {
    //     cout << it->first << " " << it->second << endl;
    // }
    // 2.for each   -std=c++11
    for (auto it : st) {
        cout << it.first << " " << it.second << endl;
    }
    return 0;
}

P2814 数对

给出一串正整数数列以及一个正整数 C,要求计算出所有满足 A−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。

分析

大多问题可以考虑暴力,如果我们现使用暴力求解,那么就是从枚举 A,B的角度出发

for A
    for B
        if(A-B==C) ans++;

这也不失为一种方法,但是我们分析发现,对于单独枚举 A 需要 n 次,单独枚举 B 需要 n 次,所以总体上枚举 (A,B) 需要 n*n 次,本题目中 \(n≤2×10^5, n^2≤4×10^{10}\) ,这个运算次数是很大的开销,会超时的。计算机1s运算次数大概可以记为 \(10^8\).

我们仔细分析,其实当枚举了 A后, B是可以直接计算出来的 B=A-C,所以我们需要统计的是 B 的次数即可。同样考虑标记思想,使用map映射。

点击查看代码
#include <bits/stdc++.h>
#include <map>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
int n, c, a[N];
LL ans = 0;
map<int, int> mp;
int main() {
    cin >> n >> c;
    for (int i = 1; i <= n; i++) {
        cin >> a[i]; mp[a[i]]++;
    }
    for (int i = 1; i <= n; i++) {
        int B = a[i] - c;
        ans += mp[B];
    }
    cout << ans;
    return 0;
}

P495 【入门】宇宙总统1

获得选票最多的人将荣登总统的宝座,如果有多个候选人获得票数一致,那么编号较大的候选人将就任总统的职位。谁是总统?

分析

需要记录最大获得票数,当具有多个最大票数时,编号最大的就是总统。

由于数据较小,可以使用标记思想,st[i] 表示编号 i 的候选人获得的票数。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1010, INF = 0x3f3f3f3f;
int n, x, st[N];
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> x; st[x]++;
    }
    int mx = 0, ans = 0;
    for (int i = 1; i <= 100; i++)
        mx = max(mx, st[i]);
    for (int i = 100; i >= 1; i--)
        if (mx == st[i]) {
            ans = i; break;
        }
    cout << ans;
    return 0;
}

P496 【入门】宇宙总统2

获得选票最多的人将荣登总统的宝座,如果有多个候选人获得票数一致,那么名字字典码最大的人将获得总统的宝座。谁是总统?

分析

和上一题逻辑相同,只是编号变成了姓名,那么考虑能否有一种映射关系,可以姓名作为自变量呢?可以使用 map映射。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;

struct T {
    string s;
    int num;
    bool operator<(const T& t) const {
        if (num != t.num) return num > t.num;
        return s > t.s;
    }
} g[N];

bool cmp(T a, T b) {
    if (a.num != b.num) return a.num > b.num;
    return a.s > b.s;
}

int main() {
    int n;
    cin >> n;
    string s;
    map<string, int> mp;
    for (int i = 1; i <= n; i++) {
        cin >> s; mp[s]++;
    }
    int p = 0;
    for (auto u : mp) // 存入结构体,以便排序
        g[++p] = {u.first, u.second};
    sort(g+1, g +1+ p); // 使用 operator<
    // sort(g+1, g + 1 +p, cmp); // 使用 cmp
    for (int i = 1; i <= p; i++)
        cout << g[i].s << " " << g[i].num << endl;
    return 0;
}

P2843 宇宙总统3

获得选票最多的人将荣登总统的宝座,如果有多个候选人获得票数一致,那么序号小的人将获得总统的宝座。谁是总统?

票数可能会很大,可能会到 100 位数字

分析 主要是比较票数,需要自定义比较方式,使用结构体存储。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;

struct T {
    string s;
    int id;
    bool operator<(const T& t) const {
        if (s.size() != t.s.size()) return s.size() > t.s.size();
        for (int i = 0; i < s.size(); i++)
            if (s[i] != t.s[i]) return s[i] > t.s[i];
        return id < t.id;
    }
} g[N];
int main() {
    int n, p = 0;
    string s;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> s;
        g[++p] = {s, i};
    }
    sort(g + 1, g + 1 + p);
    cout << g[1].id << endl << g[1].s;
    return 0;
}

P2810 相邻字符对

定义“相邻字符对”为下标相邻的两个字符,输出出现次数最多的相邻字符对,如果有多个,则按照字典序依次输出。

分析

等同于两个字符映射到这个两个字符的出现次数,可以使用map.

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
map<string, int> mp;

struct T {
    string s;
    int num;
    bool operator<(const T& t) const {
        if (num != t.num) return num > t.num;
        return s < t.s;
    }
} g[N];
int main() {
    string s;
    cin >> s;
    for (int i = 0; i < s.size() - 1; i++)
        mp[s.substr(i, 2)]++;
    int p = 0;
    for (auto u : mp)
        g[++p] = {u.first, u.second};
    sort(g + 1, g + 1 + p);
    for (int i = 1; i <= p && g[i].num == g[1].num; i++)
        cout << g[i].s << endl;
    return 0;
}

P2113 全排列问题

输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字,每行一个序列,每个数字保留5个场宽。

学习:next_permutation(begin,end);
作用:生成下一个全排列,如果有下一个全排列返回true,否则返回false.

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int n,a[N];
int main() {
    cin >> n;
    for(int i=1; i<=n; i++) a[i]=i; // 1~n
    do {
        for(int i=1; i<=n; i++) cout<<setw(5)<<a[i]; cout<<endl;
    } while( next_permutation(a+1, a+1+n) );
    return 0;
}
posted @ 2023-11-09 10:20  HelloHeBin  阅读(92)  评论(0编辑  收藏  举报