首先看到 我们都能想到去运用BFS + bool[N][N]去直接进行暴力破解,但是这个黑色点是会向负方向轴去运动的,而我们开的数组如果用了负数就是数组越界,导致该题解不出来,所以这题就需要去转换思路
-------------------------------------------------------------------------------
Tip1.将坐标轴进行移动
每次我们的x , y其中之一为负数时,我们就将他加上一个数,使他的表达值为正数去用bool记忆,但这次我们不重点讲这种方法
-------------------------------------------------------------------------------
Tip2.用map<pair<int,int>,bool>
当我们用两个点来表示一个坐标的时候,就不会出现数组越界的情况,因为我们根本没用数组
我们用map<pair<int,int>,bool>来代替bool,这样子就能代替一个二维bool数组。然后我们开两个队列queue<point>q[2];
,比如说我们刚开始储存进来4个点的是q[1],那么在q[1]进行运算时,我们储存不再储存到q[1]而是q[0]。再各运用完q[1],q[0] 2020次后,我们的bfs就走完了,最后输出mp.size();
即使最终答案
核心代码
while(cnt <= 2020){
while (q[cnt & 1].size()) { //cnt & 1:表示cnt 奇数结果为0,偶数结果为1
point u = q[cnt & 1].front(),v;
q[cnt & 1].pop();
for (int i = 0; i < 4; ++i) {
v.x = u.x + dx[i];
v.y = u.y + dy[i];
if (!mp[make_pair(v.x, v.y)]) {
mp[make_pair(v.x, v.y)] = true; //map里面的bool数组记忆
q[(cnt & 1) ^ 1].push(v); //(cnt & 1) ^ 1 表示cnt奇数结果为1,偶数结果为0
}
}
}
cnt ++; //每走完一分钟 cnt+1 走完2020分钟 结束bfs
}
完整代码
#include <iostream>
#include <map>
#include <queue>
using namespace std;
struct point{
int x,y;
}start;
map<pair<int,int>,bool>mp;
queue<point>q[2];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int main(){
//将题目给的四个点存入队列中
mp[make_pair(0,0)] = true;
start.x = 0,start.y = 0;
q[0].push(start);
mp[make_pair(2000,2000)] = true;
start.x = 2000,start.y = 2000;
q[0].push(start);
mp[make_pair(11,14)] = true;
start.x = 11,start.y = 14;
q[0].push(start);
mp[make_pair(2020,11)] = true;
start.x = 2020,start.y = 11;
q[0].push(start);
int cnt = 0;
while(cnt <= 2020){
while (q[cnt & 1].size()) { //cnt & 1:表示cnt 奇数结果为0,偶数结果为1
point u = q[cnt & 1].front(),v;
q[cnt & 1].pop();
for (int i = 0; i < 4; ++i) {
v.x = u.x + dx[i];
v.y = u.y + dy[i];
if (!mp[make_pair(v.x, v.y)]) {
mp[make_pair(v.x, v.y)] = true; //map里面的bool数组记忆
q[(cnt & 1) ^ 1].push(v); //(cnt & 1) ^ 1 表示cnt奇数结果为1,偶数结果为0
}
}
}
cnt ++; //每走完一分钟 cnt+1 走完2020分钟 结束bfs
}
cout << mp.size();
}
最终答案:20312088