PIPIOJ 1334 PIPI计数 (STL入门)

map入门题,简单。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7;
struct Node {
	int x, y;
	bool operator<(const Node& other) const {//重载运算符
		return x < other.x || x == other.x && y < other.y;
	}
}node[N];
map<Node, bool>mp;
int o[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };//对应四个方向
int main() {
	int n;
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf_s("%d %d", &node[i].x, &node[i].y);
		mp[{node[i].x, node[i].y}] = true;
	}
	for (int i = 0; i < n; i++) {
		int ans = 0;
		for (int j = 0; j < 4; j++) {//最后两个j写成i了,卡了我好长时间,淦!
			if (mp[{node[i].x + o[j][0], node[i].y + o[j][1]}])ans++;
		}
		printf("%d\n", ans);
	}
	return 0;
}

若要把结构体放入容器,需重载结构体运算符,以便容器进行排序
重载格式需要记住。

bool operator<(const Node& other) const {//这一行当做固定格式记下来
		return x < other.x || x == other.x && y < other.y;
	}

一.Map(映射)

  • 每个节点都是一个pair
  • pair类,成员变量为first,second,对应key,value。
  • 按key从小到大排序
  • 可以用[ ]访问
  • 访问一个不存在的key时自动新建一个value
  • map可用于大数据的离散化,弱审题感觉需要开一个巨大的数组,为防止越界(浪费海量空间),可以联想用容器来做题,做题也方便。
  • map时间开销大,若无需排序可使用unordered_map(unordered_map貌似需要重载双等号运算符,我还不会

二.思路波动过程

当键对应结构体,我不确定是否可以用{}输入,提交后显然是可以的。

mp[{node[i].x, node[i].y}] = true;

因为把j写成i(其实是一开始都是i,但我只改了第一个),没找到错误前,我考虑到可能不能这么写,用了保守方法,相比{}输入显得更麻烦了,但速度更快了(可以忽略不计的速度)。

for (int i = 0; i < n; i++) {
		int ans = 0;
		int xx = node[i].x;
		int yy = node[i].y;
		for (int j = 0; j < 4; j++) {
			node[i].x += o[j][0];
			node[i].y += o[j][1];
			//printf("%d %d\n", node[i].x, node[i].y);
			if (mp[node[i]])ans++;
			node[i].x = xx;
			node[i].y = yy;
		}
		printf("%d\n", ans);
	}

**

三.课程答案对比

**
未使用结构体,代码看起来更简洁轻便,思考量不知道多了还是少了(滑稽),看过课后第二次自己做想都没想用了结构体,也许这样比较顺我思路?
目前的想法是,课堂标准形散神不散,我需要结构体来固定思路。
pair也是用{}来输入。
教程答案我觉得比较好的地方是,map的count()函数,明显缩短了耗时。

if (mp.count({node[i].x + o[j][0], node[i].y+o[j][1]}))ans++;
//这样做的,简洁方便
typedef pair<int, int>pii;
map<pii, bool>mp;//注意键用pair放入用不了unordered_map,反正我不会用(滑稽)
int x[N], y[N];//直接mp[{x[i],y[i]}]输入

2020/1/23 -> 2020/2/14

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值