【模拟&STL】题解:AT_abc203_e [ABC203E] White Pawn_基础算法_数据结构_STL模板库_AtcoderABC_C++算法竞赛

文章目录

AT_abc203_e ABC203E White Pawn

题目描述

设 N N N 为正整数。有一个 ( 2 N + 1 ) × ( 2 N + 1 ) (2N+1)\times (2N+1) (2N+1)×(2N+1) 的棋盘,行和列的编号分别为 0 0 0 到 2 N 2N 2N,位于第 i i i 行第 j j j 列的格子记作 ( i , j ) (i,j) (i,j)。

棋盘上有一个白色兵,最初放在 ( 0 , N ) (0,N) (0,N)。有 M M M 个黑色兵,第 i i i 个黑色兵放在 ( X i , Y i ) (X_i, Y_i) (Xi,Yi)。

当白色兵在 ( i , j ) (i,j) (i,j) 时,你可以通过以下任一操作移动白色兵:

  • 若 0 ≤ i ≤ 2 N − 1 0\leq i\leq 2N-1 0≤i≤2N−1, 0 ≤ j ≤ 2 N 0\leq j\leq 2N 0≤j≤2N,且 ( i + 1 , j ) (i+1,j) (i+1,j) 没有黑色兵,则可以将白色兵移动到 ( i + 1 , j ) (i+1,j) (i+1,j)。
  • 若 0 ≤ i ≤ 2 N − 1 0\leq i\leq 2N-1 0≤i≤2N−1, 0 ≤ j ≤ 2 N − 1 0\leq j\leq 2N-1 0≤j≤2N−1,且 ( i + 1 , j + 1 ) (i+1,j+1) (i+1,j+1) 有黑色兵,则可以将白色兵移动到 ( i + 1 , j + 1 ) (i+1,j+1) (i+1,j+1)。
  • 若 0 ≤ i ≤ 2 N − 1 0\leq i\leq 2N-1 0≤i≤2N−1, 1 ≤ j ≤ 2 N 1\leq j\leq 2N 1≤j≤2N,且 ( i + 1 , j − 1 ) (i+1,j-1) (i+1,j−1) 有黑色兵,则可以将白色兵移动到 ( i + 1 , j − 1 ) (i+1,j-1) (i+1,j−1)。

黑色兵不能移动。

请你求出,经过若干次操作后,白色兵最终可以到达 ( 2 N , Y ) (2N,Y) (2N,Y) 的不同 Y Y Y 的个数。

输入格式

输入通过标准输入给出,格式如下:

N N N M M M X 1 X_1 X1 Y 1 Y_1 Y1 : : : X M X_M XM Y M Y_M YM

输出格式

输出答案。

输入输出样例 #1

输入 #1

复制代码
2 4
1 1
1 2
2 0
4 2

输出 #1

复制代码
3

输入输出样例 #2

输入 #2

复制代码
1 1
1 1

输出 #2

复制代码
0

说明/提示

限制条件

  • 1 ≤ N ≤ 10 9 1\leq N\leq 10^9 1≤N≤109
  • 0 ≤ M ≤ 2 × 10 5 0\leq M\leq 2\times 10^5 0≤M≤2×105
  • 1 ≤ X i ≤ 2 N 1\leq X_i\leq 2N 1≤Xi≤2N
  • 0 ≤ Y i ≤ 2 N 0\leq Y_i\leq 2N 0≤Yi≤2N
  • ( X i , Y i ) ≠ ( X j , Y j ) (X_i, Y_i)\neq (X_j, Y_j) (Xi,Yi)=(Xj,Yj)( i ≠ j i\neq j i=j)
  • 所有输入均为整数。

样例解释 1

可以分别如下移动到 ( 4 , 0 ) (4,0) (4,0)、 ( 4 , 1 ) (4,1) (4,1)、 ( 4 , 2 ) (4,2) (4,2) 这三个位置:

  • ( 0 , 2 ) → ( 1 , 1 ) → ( 2 , 1 ) → ( 3 , 1 ) → ( 4 , 2 ) (0,2)\to (1,1)\to (2,1)\to (3,1)\to (4,2) (0,2)→(1,1)→(2,1)→(3,1)→(4,2)
  • ( 0 , 2 ) → ( 1 , 1 ) → ( 2 , 1 ) → ( 3 , 1 ) → ( 4 , 1 ) (0,2)\to (1,1)\to (2,1)\to (3,1)\to (4,1) (0,2)→(1,1)→(2,1)→(3,1)→(4,1)
  • ( 0 , 2 ) → ( 1 , 1 ) → ( 2 , 0 ) → ( 3 , 0 ) → ( 4 , 0 ) (0,2)\to (1,1)\to (2,0)\to (3,0)\to (4,0) (0,2)→(1,1)→(2,0)→(3,0)→(4,0)

另一方面,无法移动到 ( 4 , 3 ) (4,3) (4,3) 和 ( 4 , 4 ) (4,4) (4,4)。因此,输出 3 3 3。

样例解释 2

无法将白色兵从 ( 0 , 1 ) (0,1) (0,1) 移动到其他位置。

由 ChatGPT 4.1 翻译


题解

简要题意:

简单模拟一下样例就会发现:

  • 如果一行一个黑子都没有,那么对答案没有帮助,原来位置的白子直接下移一格即可
  • 如果白子想脱离横坐标 N,只能是借助斜下方的黑子
    所以我们只要枚举所有黑子的位置去讨论答案就好了(呼应了M<=2e5但N<=1e9的数据范围)

看起来有点像dp的转移,可以考虑从上到下枚举有黑子的行,存储当前所有白子可能出现的列集合S(最多2N个);

再枚举当前行的黑子,判断两个事:

  • 其斜上方是否存在白子,若存在,把它的纵列加入S
  • 其正上方是否存在白子,若存在,把它的纵列从S中移出(因为正下方有黑子时白子没办法继续下移了)

存储黑子可以用map,自动按照第一、二维排序。

考虑如何维护集合S,发现我们需要快速查找是否存在对应下标以及插入、删除操作,不难想到用set维护

时间复杂度降至O(mlogm)

cpp 复制代码
// code by https://www.luogu.com.cn/article/ref58umu
#include <bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	map<int,vector<int>> Map;
	set<int> Set;
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		Map[x].push_back(y);
	}
	Set.insert(n);
	for(auto i:Map)
	{
		vector<int> in,out;
		for(int j:i.second)
		{
			if(Set.count(j)) out.push_back(j);
			if(Set.count(j-1)||Set.count(j+1)) in.push_back(j);
		}
		for(int j:out) Set.erase(j);
		for(int j:in) Set.insert(j);
	}
	printf("%d",Set.size());
	return 0;
}
相关推荐
·present·1 小时前
CSAPP(lecture 10)
c语言·c++
啊啊啊啊啊!!!!1 小时前
【c++】⽤哈希表封装myunordered_map和myunordered_set
数据结构·哈希算法·散列表
xiaolang_8616_wjl1 小时前
c++游戏_宝可梦大世界(源代码)
开发语言·c++·游戏
(●—●)橘子……1 小时前
力扣 第525场周赛 练习理解
数据结构·python·学习·算法·leetcode
Tt有了t1 小时前
Redis的数据结构
数据结构·数据库·redis
Rain的Java大神之路1 小时前
LeetCode 21 合并两个有序链表:一道 Easy 题,凭什么刷掉一半候选人?
java·后端·算法
小蒋观天下1 小时前
太阳能低功耗AI相机专项:AOV值守、唤醒时序、ISP启停时序BUG
深度学习·数码相机·算法·机器学习
wenyq72 小时前
LeetCode 152. Maximum Product Subarray
java·算法·leetcode
余额瞒着我当琳2 小时前
C++异常,异常的概念,异常抛出与捕获,RAII 和智能指针的设计思路,C++标准库一些指针的使用
java·开发语言·c++·算法