CCF认证201912-2. 回收站选址

欢迎访问我的CCF认证考试题解目录哦

题目描述

算法设计

由于输入的坐标 ( x , y ) (x,y) (x,y)均满足 ∣ x ∣ , ∣ y ∣ ≤ 1 0 9 |x|,|y|\leq10^9 x,y109,且 x , y x,y x,y可为负数,我们不可能开辟一个二维数组来存储这些坐标。而且由于输入坐标个数 n n n满足 1 ≤ n ≤ 1 0 3 1\leq n \leq 10^3 1n103,我们可以使用一个map来存储这些坐标。我们可以用array类型代表坐标,用另一个array存储坐标上下左右四个邻居位置存在垃圾的个数和四个对角位置中存在垃圾的个数。这样我们就可以用一个map, array来存储一个坐标和其对应的要考虑的量了。

C++代码

#include 
using namespace std;
using gg = long long;  //类型别名
int main() {
     
    ios::sync_with_stdio(false);
    //键为坐标,值对应该坐标上下左右四个邻居位置存在垃圾的个数和四个对角位置中存在垃圾的个数
    map<array<gg, 2>, array<gg, 2>> m;
    gg n;
    array<gg, 2> p;
    cin >> n;
    while (n--) {
     
        cin >> p[0] >> p[1];
        m.insert({
     p, {
     0, 0}});  //将当前坐标插入哈希表中,默认邻居位置和对角位置垃圾个数均为0
        for (auto& i : m) {
     
            auto& p2 = i.first;
            if ((abs(p[0] - p2[0]) == 1 and p[1] == p2[1]) or
                (p[0] == p2[0] and abs(p[1] - p2[1]) == 1)) {
       //邻居位置存在垃圾
                ++m[p][0];
                ++m[p2][0];
            } else if (abs(p[0] - p2[0]) == 1 and abs(p[1] - p2[1]) == 1) {
       //对角位置存在垃圾
                ++m[p][1];
                ++m[p2][1];
            }
        }
    }
    array<gg, 5> ans{
     };  //存储最终结果
    for (auto& i : m)
        if (i.second[0] == 4)  //当前坐标可以作为选址
            ++ans[i.second[1]];  //递增其得分下的选址个数
    for (auto i : ans)
        cout << i << "\n";
    return 0;
}

你可能感兴趣的:(CCF)