1. 程式人生 > >[BZOJ1193][HNOI2006]馬步距離 大範圍貪心小範圍爆搜

[BZOJ1193][HNOI2006]馬步距離 大範圍貪心小範圍爆搜

次數 mat scrip -1 input ios width clu clas

1193: [HNOI2006]馬步距離

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1988 Solved: 905
[Submit][Status][Discuss]

Description

在國際象棋和中國象棋中,馬的移動規則相同,都是走“日”字,我們將這種移動方式稱為馬步移動。如圖所示, 從標號為 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 至少 需要經過多少次馬步移動? 技術分享

Input

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

Output

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

Sample Input

1 2 7 9

Sample Output

5 技術分享
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<algorithm>
 7
using namespace std; 8 int tx[10]={1,2,1,2,-1,-2,-1,-2}; 9 int ty[10]={2,1,-2,-1,2,1,-2,-1}; 10 int xp,yp,xs,ys; 11 int dis[105][105]; 12 int q1[1005],q2[1005]; 13 int bfs(int x,int y) { 14 memset(dis,-1,sizeof(dis)); 15 int s=0,t=1; 16 q1[s]=x;q2[s]=y; 17 dis[x][y]=0; 18 while(s!=t) { 19
int nx=q1[s++],ny=q2[s-1];if(s==1000) s=0; 20 for(int i=0;i<8;i++) { 21 int tox=nx+tx[i],toy=ny+ty[i]; 22 if(tox<0||toy<0||tox>60||toy>60||dis[tox][toy]!=-1) continue; 23 dis[tox][toy]=dis[nx][ny]+1; 24 q1[t]=tox,q2[t++]=toy;if(t==1000) t=0; 25 } 26 } 27 return dis[30][30]; 28 } 29 int main() { 30 scanf("%d%d%d%d",&xp,&yp,&xs,&ys); 31 int x=abs(xp-xs),y=abs(yp-ys); 32 int cnt=0; 33 while(x+y>=30) { 34 if(x<y) swap(x,y); 35 if(x-4>=y*2) x-=4; 36 else x-=4,y-=2; 37 cnt+=2; 38 } 39 x+=30,y+=30; 40 printf("%d",cnt+bfs(x,y)); 41 return 0; 42 }
View Code

[BZOJ1193][HNOI2006]馬步距離 大範圍貪心小範圍爆搜