用unordered_map能直接过所有样例不用优化
代码A和代码B在解决农夫抓牛的问题时,都采用了广度优先搜索(BFS)的方法,但它们在处理一些细节时有所不同,导致代码A能够正确运行而代码B在某些情况下会出错。
代码A的正确性分析
数据结构选择:
代码A使用了unordered_map[HTML_REMOVED]来记录每个位置的最短到达时间。unordered_map可以高效地处理稀疏数组的情况,因为数轴上的点可能非常分散。
初始化:
代码A在初始化时,将unordered_map的所有可能位置(从-N到N)的值设为-1,表示这些位置尚未访问。这确保了即使位置非常远,也能被正确处理。
边界条件:
代码A在每次移动时都检查了新位置x是否大于等于0,这避免了访问负数位置,符合题目要求。
搜索逻辑:
代码A的搜索逻辑清晰,分别处理了向前、向后和乘以2的三种移动方式。
代码B的问题分析
数组大小:
代码B使用了固定大小的数组int s[N]来记录每个位置的最短到达时间。虽然这通常是一个有效的方法,但在这个问题中,由于农夫和牛的位置可能非常远(最大可以到10^5),数组s可能会超出其定义的范围,导致未定义行为(如访问越界)。
初始化:
代码B使用memset(s, -1, sizeof s)来初始化数组,这是正确的。但由于数组大小可能不足以覆盖所有可能的数轴位置,这可能导致问题。
边界条件:
代码B同样检查了新位置x是否大于等于0,这是正确的。
搜索逻辑:
代码B的搜索逻辑与代码A相同,也是正确的。
为什么代码B只能过部分样例
数组大小限制:代码B的主要问题在于它使用了固定大小的数组来存储状态。当农夫和牛的位置非常远时,这个数组可能不足以覆盖所有可能的数轴位置,导致未定义行为(如访问数组越界)。
内存限制:即使数组大小足够,使用如此大的数组也可能导致内存超出限制,特别是在处理大量数据时。
结论
代码A通过使用unordered_map来避免数组大小的问题,并且能够高效地处理稀疏数组的情况,因此能够正确运行。
代码B虽然逻辑正确,但由于数组大小限制和可能的内存问题,只能过部分样例。
因此,在处理这类问题时,选择适当的数据结构(如unordered_map)和确保足够的内存空间是非常重要的。
#include<unordered_map>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N = 1e5 + 10;
queue<int>q;
unordered_map<int, int>s;
int n, k;
int d[2] = { 1,-1 };
int bfs()
{
q.push(n);
s[n] = 0;
while (!q.empty())
{
auto now = q.front();
q.pop();
if (now == k)
return s[k];
for (int i = 0; i < 3; i++)
{
//分别执行前进 后退两个操作
if (i <= 1)
{
int x = now + d[i];
if (s[x] == -1&&x>=0)
{
q.push(x);
s[x] = s[now] + 1;
}
}
else //执行 2* 操作
{
int x = now>>1;
if (s[x] == -1 && x >= 0)
{
q.push(x);
s[x] = s[now] + 1;
}
}
}
}
}
int main()
{
for (int i = -N; i <= N; i++)
s[i] = -1;
cin >> n >> k;
if (n >= k)
cout << n - k << endl;
else
cout<<bfs();
return 0;
}