题目描述
爱与愁大神坐在公交车上无聊,于是玩起了手机。一款奇怪的游戏进入了爱与愁大神的眼帘:***(游戏名被打上了马赛克)。这个游戏类似象棋,但是只有黑白马各一匹,在点x1,y1和x2,y2上。它们得从点x1,y1和x2,y2走到1,1。这个游戏与普通象棋不同的地方是:马可以走“日”,也可以像象走“田”。现在爱与愁大神想知道两匹马到1,1的最少步数,你能帮他解决这个问题么?
输入输出格式
输入格式:
第1行:两个整数x1,y1
第2行:两个整数x2,y2
输出格式:
第1行:黑马到1,1的距离
第2行:白马到1,1的距离
输入输出样例
说明
100%数据:x1,y1,x2,y2<=20
读题再结合数据范围,很明显是一道搜索题,对于题目中说马可以走日也可以走田,画个图就知道
1 1 1 1
1 1
1 1
1 1 1 1
搜索方式变成了一个正方形而已
改动后的方向数组如下
int dx[]={-2,-1,1,2,-2,2,-2,2,-2,-1,1,2}; int dy[]={2,2,2,2,1,1,-1,-1,-2,-2,-2,-2};
再考虑怎么搜,dfs还是bfs,由于dfs会求出所有可能,所以dfs更适用于多结果的搜索,而bfs只是求一个最优解,故更适用于单结果搜索(然而很多搜索题bfs和dfs都可以做,选哪个差别不大,主要看个人喜好)
先说dfs的做法
先考虑起点,题目中说有两匹马,一开始准备要做两次搜索分别求解,但是后来发现题目可以转化为从终点出发到两匹马位置,就只要搜索一次,搜索时记录下从起点到每个点的距离,直接输出到两匹马的距离就好
代码如下
void dfs(int x,int y) { if(a[x][y]&&a[x][y]<=s)return; a[x][y]=s;++s; for(int i=0;i<12;i++) { int xx=x+dx[i],yy=y+dy[i]; if(xx>=1&&yy>=1&&xx<=20&&yy<=20&&!vis[xx][yy]) { vis[x][y]=1; dfs(xx,yy); vis[x][y]=0; } } --s; }
再说bfs的做法,思路同上,转化为从终点出发到两匹马位置,其实这道题bfs比dfs更好,因为求最短路径时bfs可以确保第一次出最优解,效率更高
代码如下
void bfs(int x,int y) { int h=0,t=1; que[t][0]=x; que[t][1]=y; vis[x][y]=1; while(h<t) { h++; for(int i=0;i<12;i++) { int xx=que[h][0]+dx[i],yy=que[h][1]+dy[i]; if(xx>=1&&yy>=1&&xx<=20&&yy&&!vis[xx][yy]) { t++; que[t][0]=xx; que[t][1]=yy; vis[xx][yy]=1; a[xx][yy]=a[que[h][0]][que[h][1]]+1; } } }
完整代码如下
#include<bits/stdc++.h> using namespace std; int x1,y11,x2,y2,s,a[25][25],que[10005][3]; int dx[]={-2,-1,1,2,-2,2,-2,2,-2,-1,1,2}; int dy[]={2,2,2,2,1,1,-1,-1,-2,-2,-2,-2}; bool vis[25][25]; /*void dfs(int x,int y) { if(a[x][y]&&a[x][y]<=s)return; a[x][y]=s;++s; for(int i=0;i<12;i++) { int xx=x+dx[i],yy=y+dy[i]; if(xx>=1&&yy>=1&&xx<=20&&yy<=20&&!vis[xx][yy]) { vis[x][y]=1; dfs(xx,yy); vis[x][y]=0; } } --s; }*/ void bfs(int x,int y) { int h=0,t=1; que[t][0]=x; que[t][1]=y; vis[x][y]=1; while(h<t) { h++; for(int i=0;i<12;i++) { int xx=que[h][0]+dx[i],yy=que[h][1]+dy[i]; if(xx>=1&&yy>=1&&xx<=20&&yy&&!vis[xx][yy]) { t++; que[t][0]=xx; que[t][1]=yy; vis[xx][yy]=1; a[xx][yy]=a[que[h][0]][que[h][1]]+1; } } } } int main() { cin>>x1>>y11>>x2>>y2; // dfs(1,1); bfs(1,1); cout<<a[x1][y11]<<endl<<a[x2][y2]; return 0; }
dfs部分参考大佬@小菜鸟题解