首页 > 代码库 > poj-1915- Knight Moves
poj-1915- Knight Moves
题目大意:给一个边长为len的棋盘,然后给出起点和终点的坐标,求马从起点到终点最少需要走几步!
题解:这个题的题意是很好理解的,要求我们求最少需要走的步数,我们在这可以想到用bfs来解决这个问题,由于在这个棋盘中,马棋有八种路可以选择进行跳跃,所以开辟两个方向数组xx[]和yy[],然后再进行相应操作即可!
这道题我写了四次,用了不同的方法,区别其实也不大,只是写法的问题!这个题其实只要是选择使用了bfs的话,没什么细节问题的话,都是能AC的,不过用时有些不同!
第一种是最快的,是用的数组写的队列!
下面是我写的四份代码:
#include<stdio.h> #include<string.h> int t,len,sx,sy,lx,ly; int vis[315][315]; int xx[8]= {1,1,-2,-2,2,2,-1,-1}; int yy[8]= {-2,2,1,-1,1,-1,2,-2}; struct Node { int x,y,step; }knight[201314]; int knight_moves(int n) { Node dangqi; Node change; int first=0,last=1; //头.尾! knight[0].x=sx; knight[0].y=sy; knight[0].step=0; memset(vis,0,sizeof(vis)); while(last>first) { dangqi=knight[first++];//此处为出队! if(dangqi.x==lx&&dangqi.y==ly) return dangqi.step; else { for(int i=0;i<8;i++) { int X=dangqi.x+xx[i]; int Y=dangqi.y+yy[i]; if(X>=0&&X<n&&Y>=0&&Y<n&&vis[X][Y]==0) { vis[X][Y]=1; change.x=X; change.y=Y; change.step=dangqi.step+1;//棋子移动一次,步数step就加一次! knight[last++]=change;//入队! } } } } } int main() { scanf("%d",&t); while(t--) { scanf("%d",&len); scanf("%d%d",&sx,&sy); scanf("%d%d",&lx,&ly); int ans=knight_moves(len); printf("%d\n",ans); } return 0; }
第二种:用的STL模板写的!
#include<cstdio> #include<cstring> #include<queue> #include<iostream> using namespace std; int len,sx,dx,sy,dy; bool vis[315][315]; int xx[8]={1,1,-2,-2,2,2,-1,-1}; int yy[8]={-2,2,1,-1,1,-1,2,-2}; struct horse { int x,y,step; }now; void knight_moves(int n) { queue<horse>Q; memset(vis,false,sizeof(vis)); now.x=sx,now.y=sy,now.step=0; Q.push(now); while(!Q.empty()) { horse u=Q.front(); Q.pop(); if(u.x==dx&&u.y==dy) { cout<<u.step<<endl; return ; } for(int i=0;i<8;i++) { int X=xx[i]+u.x; int Y=yy[i]+u.y; if(!vis[X][Y]&&X>=0&&X<n&&Y>=0&&Y<n) { vis[X][Y]=true; horse v; v.x=X,v.y=Y,v.step=u.step+1; Q.push(v); } } } } int main() { int T; cin>>T; while(T--) { cin>>len>>sx>>sy>>dx>>dy; knight_moves(len); } return 0; }
第三种:
#include<cstdio> #include<cstring> #include<queue> #include<iostream> using namespace std; int len,sx,dx,sy,dy; bool vis[315][315]; int step[315][315]; int xx[8]={1,1,-2,-2,2,2,-1,-1}; int yy[8]={-2,2,1,-1,1,-1,2,-2}; void knight_moves(int n) { queue<int>Q; memset(vis,false,sizeof(vis)); memset(step,0,sizeof(step)); Q.push(sx); Q.push(sy); while(!Q.empty()) { int x=Q.front(); Q.pop(); int y=Q.front(); Q.pop(); if(x==dx&&y==dy) { printf("%d\n",step[x][y]); return ; } for(int i=0;i<8;i++) { int X=xx[i]+x; int Y=yy[i]+y; if(!vis[X][Y]&&X>=0&&X<n&&Y>=0&&Y<n) { vis[X][Y]=true; step[X][Y]=step[x][y]+1; Q.push(X); Q.push(Y); } } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&len); scanf("%d%d",&sx,&sy); scanf("%d%d",&dx,&dy); knight_moves(len); } return 0; }
第四种:
#include<cstdio> #include<cstring> #include<queue> #include<iostream> using namespace std; int len,sx,dx,sy,dy; bool vis[315][315]; int step[315][315]; int xx[8]={1,1,-2,-2,2,2,-1,-1}; int yy[8]={-2,2,1,-1,1,-1,2,-2}; void knight_moves(int n) { queue<int>Qx; queue<int>Qy; memset(vis,false,sizeof(vis)); memset(step,0,sizeof(step)); Qx.push(sx); Qy.push(sy); while(!Qx.empty()) { int x=Qx.front(); Qx.pop(); int y=Qy.front(); Qy.pop(); //vis[x][y]=false; if(x==dx&&y==dy) { printf("%d\n",step[x][y]); return ; } for(int i=0;i<8;i++) { int X=xx[i]+x; int Y=yy[i]+y; if(!vis[X][Y]&&X>=0&&X<n&&Y>=0&&Y<n) { vis[X][Y]=true; step[X][Y]=step[x][y]+1; Qx.push(X); Qy.push(Y); } } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&len); scanf("%d%d",&sx,&sy); scanf("%d%d",&dx,&dy); knight_moves(len); } return 0; }
poj-1915- Knight Moves
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。