CSP 201912-2 回收站选址 100分

[题目背景]
开学了,可是校园里堆积了不少垃圾杂物。
热心的同学们纷纷自发前来清理,为学校注入正能量~

[题目描述]
通过无人机航拍我们已经知晓了n处尚待清理的垃圾位置,其中第i (1≤i≤n)处的坐标为(x, y),保证所有的坐标均为整数。
我们希望在垃圾集中的地方建立些回收站。具体来说,对于-一个位置(x,y)是否适合建立回收站,我们主要考虑以下几点:
●(x,y)必须是整数坐标,且该处存在垃圾;
●上下左右四个邻居位置,即(x,y+ 1)、(x,y-1)、(x+ 1,y)和(x-1,y)处,必须全部存在垃圾;
●进一步地,我们会对满足上述两个条件的选址进行评分,分数为不大于4的自然数,表示在(x土1,y土1)四个对角位置中有几处存在垃圾。
现在,请你统计一下每种得分的选址个数。

[输入格式]
从标准输入读入数据。
输入总共有n+1行。
第1行包含一个正整数n,表示已查明的垃圾点个数。
第1+i行(1≤i≤n)包含由一个空格分隔的两个整数x;和y,表示第i处垃圾的坐标。
保证输入的n个坐标互不相同。

[输出格式]
输出到标准输出。
输出共五行,每行一个整数,依次表示得分为0、1、2、3和4的回收站选址个数。

[样例1输入]
7
1 2
2 1
0 0
1 1
1 0
2 0
0 1

[样例1输出]
0
0
1
0
0

[样例1解释]
如图所示,仅有(1,1)可选为回收站地址,评分为2。.

[样例2输入]
2
0 0
-100000 10

[样例2输出]
0
0
0
0
0

[样例2解释]
不存在可选地址。

[样例3输入]
11
9 10
10 10
11 10
12 10
13 10
11 9
11 8
12 9
10 9
10 11
12 11

[样例3输出]
0
2
1
0
0

[样例3解释]
1分选址:(10,10)和(12,10);2分选址:(11,9)。

[子任务]
●测试点1和2,保证对于任意的i皆满足0≤xi,yi≤2;
●测试点3、4和5,保证对于任意的i皆满足0≤xi,yi≤500;
●测试点6、7和8,保证对于任意的i皆满足0≤xi,yi≤10;
●测试点9和10,保证对于任意的i皆满足|xi|,|yi|≤10^9,即坐标可以是负数。所有的测试点保证1≤n≤10³。

[提示]
本题中所涉及的坐标皆为整数,且保证输入的坐标两两不同。

[设计思路]
①主要数据结构设计:变量n输入垃圾点的总个数,cnt数组对不同得分的回收站选址进行计数,vector<pair<int,int> > pos用于保存所有垃圾点的坐标,然后对其进行遍历,得到结果。

②算法设计:输入垃圾点的总个数n以后,分别输入n个点的坐标(x,y)保存到vector<pair<int,int> > pos中,然后遍历pos中n个点,对每个点首先判断其上下左右四处是否均有垃圾,这是成为回收站选址的必要条件,如果不符合就直接进入下一个点的判断;如果符合,则进一步判断其四个对角位置是否有垃圾,计算其得分temp,然后根据temp的值对应的cnt数组中0、1、2、3、4的计数加1。最后依次输出cnt数组中得分为0、1、2、3、4的回收站选址的数值,即实现了题目的要求。

100分代码:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
      int n,cnt[5]={0};
      vector<pair<int,int> > pos;//保存所有垃圾点的坐标 
      cin>>n;
      for(int i=0;i<n;i++)
      {
             int x,y;
             cin>>x>>y;
             pos.push_back({x,y});
      }
      for(int i=0;i<n;i++)
      {
             int x=pos[i].first,y=pos[i].second,flag=0;
             for(int j=0;j<n;j++)
             {
                    if(pos[j].first==x-1&&pos[j].second==y)
                           flag++;
                    if(pos[j].first==x+1&&pos[j].second==y)
                           flag++;
                    if(pos[j].first==x&&pos[j].second==y-1)
                           flag++;
                    if(pos[j].first==x&&pos[j].second==y+1)
                           flag++;
             }//判断是否符合上下左右四处都有垃圾 
             if(flag==4)
             {
                    int temp=0;
                    for(int j=0;j<n;j++)
                    {
                           if(pos[j].first==x-1&&pos[j].second==y-1)
                                  temp++;
                           if(pos[j].first==x-1&&pos[j].second==y+1)
                                  temp++;
                           if(pos[j].first==x+1&&pos[j].second==y-1)
                                  temp++;
                           if(pos[j].first==x+1&&pos[j].second==y+1)
                                  temp++;
                    }
                    cnt[temp]++;
             }//判断四个对角位置有几处有垃圾,并用cnt数组对不同得分的回收站选址计数 
      }
      for(int i=0;i<5;i++)
             cout<<cnt[i]<<endl;
      return 0;
}

[小结]
201912的第2题,我从读题到提交通过大约用了30分钟时间,稍微用了一些时间思考。题目内容是垃圾回收站选址,给你所有垃圾的坐标,最后依次输出得分为0、1、2、3、4的回收站选址个数。这道题目因为后面的测试点x、y的范围非常大,而且坐标x、y还可以是负数,所以肯定不可能用二维数组作为坐标用0、1标记来进行模拟,不然只能得到一小部分分数。

这里我选择用vector存放每个x、y数对pair<int,int>,然后遍历vector,依次对每个垃圾坐标进行判断,首先要符合上下左右四处都有垃圾,如果不符合就直接进入下一个;若符合则再统计四个对角是否有垃圾,用cnt数组统计得分0、1、2、3、4的回收站个数,这样做时间复杂度也就是O(n²),这里n最大不超过10³,所以肯定是能够通过的,一次提交就通过了平台测试。

在平时ACM俱乐部的训练以及自己进行一些练习之下,我现在的水平通过前两题应该问题不是很大,考试的时候细心一点即可。我会再接再厉,充分利用暑假的时间,自主学习一些数据结构和算法的知识,努力在后面三道题目进行一些突破,争取在9月份的CSP认证考试中取得理想的成绩。

猜你喜欢

转载自blog.csdn.net/weixin_46283740/article/details/107503185