CSP题解目录

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

  • 解题思路
    • 数据存储
    • 数据处理
  • 错误原因
  • 改正思路
  • 疑问求解

得分:50

解题思路

  1. 数据存储:用一个二维数组loc[maxn+5][maxn+5]存储垃圾坐标,其中有垃圾置1,无垃圾置0。用score[5]数组存储5种得分的回收站个数。
  2. 数据处理
    步骤一,确定回收站的位置:(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;
}

错误原因

  1. 题目中测试点6~9的要求是|x|,|y|≤109,上面代码中使用的int类型无法存储所有的垃圾点坐标。

    c/c++中int,long long的取值范围如下:

数据类型最小值最大值
unsigned int0232-1(4,294,967,295)
int-231231-1(2,147,483,647)
long long-9,223,372,036,854,775,8089,223,372,036,854,775,807

改正思路,未完待续

参考博客

  1. 使用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;
}

疑问求解

  1. 将int更改成long long类型后编译出错,还没有搞清楚原因;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值