1. 程式人生 > >bzoj1193:馬步距離

bzoj1193:馬步距離

for swa ems return tail main 象棋 soft mes

題目描述

在國際象棋和中國象棋中,馬的移動規則相同,都是走“日”字,我們將這種移動方式稱為馬步移動。如圖所示, 從標號為 0 的點出發,可以經過一步馬步移動達到標號為 1 的點,經過兩步馬步移動達到標號為 2 的點。任給 平面上的兩點 p 和 s ,它們的坐標分別為 (xp,yp) 和 (xs,ys) ,其中,xp,yp,xs,ys 均為整數。從 (xp,yp) 出發經過一步馬步移動可以達到 (xp+1,yp+2)、(xp+2,yp+1)、(xp+1,yp-2)、(xp+2,yp-1)、(xp-1,yp+2)、(xp-2, yp+1)、(xp-1,yp-2)、(xp-2,yp-1)。假設棋盤充分大,並且坐標可以為負數。現在請你求出從點 p 到點 s 至少 需要經過多少次馬步移動? 技術分享

輸入

只包含4個整數,它們彼此用空格隔開,分別為xp,yp,xs,ys。並且它們的都小於10000000。

輸出

含一個整數,表示從點p到點s至少需要經過的馬步移動次數。

樣例輸入

1 2 7 9

樣例輸出

5 題解
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 int u[10]={1,1,2,2,-1,-1,-2,-2},p[10]={2,-2,1,-1,2,-2,1,-1};
 6 int sx,sy,ex,ey;
7 int q[10005][3]; 8 int ans,dis[105][105]; 9 bool ok(int x,int y) 10 { 11 if(x<0||y<0||x>100||y>100)return false; 12 return true; 13 } 14 void bfs(int x,int y) 15 { 16 memset(dis,-1,sizeof(dis)); 17 int head=0,tail=1; 18 q[0][0]=x;q[0][1]=y;dis[x][y]=0; 19 while(head!=tail) 20 {
21 int xx=q[head][0],yy=q[head++][1]; 22 for(int i=0 ; i<8 ; ++i) 23 { 24 int dx=u[i]+xx; 25 int dy=p[i]+yy; 26 if(!ok(dx,dy)||dis[dx][dy]!=-1)continue; 27 dis[dx][dy]=dis[xx][yy]+1; 28 if(dx==50&&dy==50)return ; 29 q[tail][0]=dx;q[tail++][1]=dy; 30 } 31 } 32 } 33 int main() 34 { 35 scanf("%d%d%d%d",&sx,&sy,&ex,&ey); 36 int x=abs(sx-ex),y=abs(sy-ey); 37 while(x+y>=50) 38 { 39 if(x<y)swap(x,y); 40 x-=4; 41 if(x-4<2*y)y-=2; 42 ans+=2; 43 } 44 x+=50;y+=50; 45 bfs(x,y); 46 printf("%d",ans+dis[50][50]); 47 return 0; 48 }

bzoj1193:馬步距離