CCF认证 201912-2. 回收站选址
- 解题思路
- 数据存储
- 数据处理
- 错误原因
- 改正思路
- 疑问求解
得分:50
解题思路
- 数据存储:用一个二维数组loc[maxn+5][maxn+5]存储垃圾坐标,其中有垃圾置1,无垃圾置0。用score[5]数组存储5种得分的回收站个数。
- 数据处理:
步骤一,确定回收站的位置:(1)该处存在垃圾:loc[x][y] 为真,且上、下、左、右四个邻居位置存在垃圾:loc[x][y+1] && loc[x][y-1] && loc[x+1][y] && loc[x-1][y]都为真;
步骤二,计算回收站的得分:用一个计数变量cnt,初始值为0,依次判断四个对角位置是否有垃圾,若有,则cnt++。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10000;
int loc[maxn+5][maxn+5]={0}; //垃圾坐标
//有垃圾的坐标置1,无垃圾的坐标置0
int main(){
int n; //垃圾点个数
int score[5] = {0}; //5种得分的回收站个数
scanf("%d", &n);
while (n--){
int x, y;
scanf("%d", &x);
scanf("%d", &y);
loc[x][y] = 1;
}
//1、确定回收站的位置
//该处存在垃圾:loc[x][y]
//上下左右四个邻居位置存在垃圾:loc[x][y+1] && loc[x][y-1] && loc[x+1][y] && loc[x-1][y]
//2、计算回收站的得分
for (int x=0; x<maxn+5; x++){
for (int y=0; y<maxn+5; y++){
if (loc[x][y]){
int cnt = 0;
if (loc[x][y+1] && loc[x][y-1] && loc[x+1][y] && loc[x-1][y]){
if (loc[x+1][y+1])
cnt++;
if (loc[x+1][y-1])
cnt++;
if (loc[x-1][y+1])
cnt++;
if (loc[x-1][y-1])
cnt++;
score[cnt]++;
}
}
}
}
//输出不同得分的回收站选址个数
for (int i=0; i<5; i++){
printf("%d\n", score[i]);
}
return 0;
}
错误原因
-
题目中测试点6~9的要求是|x|,|y|≤109,上面代码中使用的int类型无法存储所有的垃圾点坐标。
c/c++中int,long long的取值范围如下:
数据类型 | 最小值 | 最大值 |
---|---|---|
unsigned int | 0 | 232-1(4,294,967,295) |
int | -231 | 231-1(2,147,483,647) |
long long | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 |
改正思路,未完待续
- 使用set进行高效查找
得分:100
#include<cstdio>
#include<set>
using namespace std;
//如果元素是结构体,可以直接将比较函数写在结构体内
struct Point{
int x;
int y;
Point(int _x, int _y): x(_x), y(_y){}
//重载“<”操作符,自定义排序规则
bool operator < (const Point &rhs) const {
if(x==rhs.x) return y<rhs.y;
return x<rhs.x;
}
};
int n;
int ans[5];
set<Point> pts;
bool find(int x, int y){
if(pts.find(Point(x, y)) != pts.end()) return true;
return false;
}
int main(){
scanf("%d",&n);
int x, y;
for(int i=0;i<n;++i){
scanf("%d%d", &x, &y);
pts.insert(Point(x, y));
}
set<Point>::iterator it;
for(it=pts.begin(); it!=pts.end(); it++){
x=(*it).x;
y=(*it).y;
if(find(x, y+1) && find(x, y-1) && find(x+1, y) && find(x-1, y) ){
int cnt=0;
if(find(x-1, y+1)) cnt++;
if(find(x+1, y+1)) cnt++;
if(find(x-1, y-1)) cnt++;
if(find(x+1, y-1)) cnt++;
ans[cnt]++;
}
}
for(int i=0; i<5; ++i){
printf("%d\n", ans[i]);
}
return 0;
}
疑问求解
- 将int更改成long long类型后编译出错,还没有搞清楚原因;