Bzoj 1193
coc youyl
posted @ 2015年7月02日 16:24
in bzoj
, 638 阅读
题目分类:乱搞,贪心
题意:
给出平面上的两个坐标,从一个开始按照棋子马的移动规则移动,问最小步数。
题解:
大范围贪心,小范围暴力。
注意贪心时要考虑一维极小一维极大的情况,所以要将两步合并为一步进行处理。
程序:
#include<cstdio> #include<queue> #include<algorithm> using namespace std; int x1,y1; int x2,y2; int tx,ty,ans; const int dir[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{-2,1},{2,-1},{-2,-1}}; int dis[220][220]; inline void bfs() { queue<int>q1,q2; q1.push(tx); q2.push(ty); dis[tx][ty]=ans+1; while (!q1.empty()) { x1=q1.front(); x2=q2.front(); q1.pop(); q2.pop(); for (int i=0;i<8;i++) { if(x1+dir[i][0]>0&&x1+dir[i][0]<=200&&x2+dir[i][1]>0&&x2+dir[i][1]<=200) { if(dis[x1+dir[i][0]][x2+dir[i][1]]==0) { dis[x1+dir[i][0]][x2+dir[i][1]]=dis[x1][x2]+1; q1.push(x1+dir[i][0]); q2.push(x2+dir[i][1]); if(x1+dir[i][0]==50&&x2+dir[i][1]==50)return; } } } } } inline int abss(int x1) { if(x1>0)return x1; return -x1; } int main() { scanf("%d %d %d %d",&x1,&y1,&x2,&y2); tx=abss(x1-x2);ty=abss(y1-y2); while (tx+ty>=50) { if(tx<ty)swap(tx,ty); if(tx-4>2*ty)tx-=4; else tx-=4,ty-=2; ans+=2; } tx+=50; ty+=50; bfs(); printf("%d\n",(-1)+dis[50][50]); return 0; }