题目描述 Description
农民John有很多牛,他想交易其中一头被Don称为The Knight的牛。这头牛有一个独一无二的超能力,在农场里像Knight一样地跳(就是我们熟悉的象棋中马的走法)。虽然这头神奇的牛不能跳到树上和石头上,但是它可以在牧场上随意跳,我们把牧场用一个x,y的坐标图来表示。
这头神奇的牛像其它牛一样喜欢吃草,给你一张地图,上面标注了The Knight的开始位置,树、灌木、石头以及其它障碍的位置,除此之外还有一捆草。现在你的任务是,确定The Knight要想吃到草,至少需要跳多少次。The Knight的位置用’K’来标记,障碍的位置用’*’来标记,草的位置用’H’来标记。
这里有一个地图的例子:
11 | … … … .
10 | … . * … . .
9 | … … … .
8 | … * . * … .
7 | … … . * . .
6 | . . * . . * … H
5 | * … … …
4 | … * … * . .
3 | . K … … . .
2 | … * … . . *
1 | . . * … . * . .
0 ———————-
1
0 1 2 3 4 5 6 7 8 9 0
The Knight 可以按照下图中的A,B,C,D…这条路径用5次跳到草的地方(有可能其它路线的长度也是5):
11 | … … … .
10 | … . * … . .
9 | … … … .
8 | … * . * … .
7 | … … . * . .
6 | . . * . . * … F<
5 | * . B … … .
4 | … * C . . * E .
3 | .>A … . D …
2 | … * … . . *
1 | . . * … . * . .
0 ———————-
1
0 1 2 3 4 5 6 7 8 9 0
输入描述 Input Description
第一行: 两个数,表示农场的列数(<=150)和行数(<=150)
第二行..结尾: 如题目描述的图。
输出描述 Output Description
一个数,表示跳跃的最小次数。
样例输入 Sample Input
10 11
……….
….*…..
……….
….….
…….*..
....…H
*………
……..
.K……..
……..
..…...
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
Hint:这类问题可以用一个简单的先进先出表(队列)来解决。
看到最小跳跃次数总想一直取min比较,实际上不用。因为是宽搜,到达同一层需要的步数相同,所以第一次搜到终点时就是最小步数了。
第一次交的时候MLE。明明数组才开到了150,就MLE了。觉得好迷,喊大胆来看,看了半天自己倒是看到了错误,判重判错了。
判重判错导致死循,好像应该RE才对,为什么是MLE??
学长说代码的空间使用量主要跟数组有关,死循环有时也会导致MLE。
有时STL会调用很多空间,具体就是:栈,队列,堆,set,map,vector存图,栈和队列搜索的搜索树偏大……
set和map利用高级数据结构的原理,所以复杂度高。
“栈和队列搜索的搜索树”大概指BFS,DFS的规模,与存的状态多少有关。存的状态多少会影响空间和时间。
所以,,如果确保数组大小合适但是MLE的时候,应当检查下有没有因为智障的错误导致死循环。
提高准确度。数据水的时候死循也会过样例,比如这次。考场上这样的话就GG了QWQ。
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1000;
char s[maxn][maxn];
bool vis[maxn][maxn];
int dx[]={1,-1,1,-1,2,2,-2,-2},dy[]={2,2,-2,-2,1,-1,1,-1};
int n,m,ans;
struct node
{
int x,y,step;
};
bool can(int x,int y,int tot)
{
if(x<=0||y<=0||x>n||y>m) return 0;
if(s[x][y]=='*') return 0;
if(vis[x][y]) return 0;
return 1;
}
int bfs(int x,int y)
{
queue q;
while(!q.empty()) q.pop();
q.push((node){x,y,0});
vis[x][y]=1;
while(!q.empty())
{
node f=q.front();
q.pop();
int k=f.step+1;
for(int i=0;i<8;i++)
{
node t;
t.x=f.x+dx[i];
t.y=f.y+dy[i];
if(can(t.x,t.y,k))
{
vis[t.x][t.y]=1;
q.push((node){t.x,t.y,k});
if(s[t.x][t.y]=='H')
{
ans=k;
return ans;
}
}
}
}
return ans;
}
int main()
{
int xx,yy;
scanf("%d%d",&m,&n);
for(int i=n;i>=1;i--)
for(int j=1;j<=m;j++)
{
cin>>s[i][j];
if(s[i][j]=='K') xx=i,yy=j;
}
printf("%d",bfs(xx,yy));
return 0;
}