记录编号 189844 评测结果 AAAAAAAAAA
题目名称 [HNOI 2006]马步距离 最终得分 100
用户昵称 Gravatarstdafx.h 是否通过 通过
代码语言 C++ 运行时间 0.013 s
提交时间 2015-09-30 08:00:08 内存使用 3.49 MiB
显示代码纯文本
#define ll long long
 
#define MAXN 210UL
 
#define BS(a) (a+6)
 
#include <cstdio>
#include <cstring>
#include <queue>
 
int a,b,xp,yp,xs,ys,Ans,f1,f2;
int dx[MAXN][MAXN];
bool ex[MAXN][MAXN];
int op1[9]={0,1,-1,-2,-2,-1, 1, 2,2};
int op2[9]={0,2, 2, 1,-1,-2,-2,-1,1};
 
std::queue<int> quex,quey;
 
inline ll ABS(ll r){return r>0?r:-r;}
inline bool Check(ll x,ll y){return x>=0&&y>=0&&a-x-(y<<1)>=0&&b-(x<<1)-y>=0;}
inline void Update(ll x,ll y){for(ll i=x-5;i<=x+5;i++) for(ll j=y-5;j<=y+5;j++) if(i+j>f1+f2&&Check(i,j)) f1=i,f2=j;return;}
inline void Push(int x,int y){quex.push(x),quey.push(y);return;}
inline bool Pos(int x,int y){return x>=-5&&y>=-5&&x<=a+10&&y<=b+10;}
 
//x=op1 (1,2)  y=op2 (2,1)
//e1:a-x-2y>=0 e2:b-2x-y>=0  ==> e3: z=x+y  f1,f2;
//P1 (0,a/2) .. P2(a,0)   .. 
//P3 (0,b)   .. P4(b/2,0) ..
//P5 ((2b-a)/3,(2a-b)/3)
 
bool flag;
 
void spfa(){
    memset(dx,50,sizeof(dx));dx[BS(0)][BS(0)]=0;
    Push(0,0);
    while(!quex.empty()){
        int tx=quex.front(),ty=quey.front();quex.pop(),quey.pop();ex[tx][ty]=0;
        for(int i=1,nx,ny;i<=8;i++){
            nx=tx+op1[i],ny=ty+op2[i];
            if(!Pos(nx,ny)) continue;
            if(dx[BS(nx)][BS(ny)]>dx[BS(tx)][BS(ty)]+1){
                dx[BS(nx)][BS(ny)]=dx[BS(tx)][BS(ty)]+1;
                if(!ex[BS(nx)][BS(ny)]){
                    ex[BS(nx)][BS(ny)]=1;
                    Push(nx,ny);
                }
            }
        }
    }
    Ans+=dx[BS(a)][BS(b)];
    return;
}
 
int main(){
	freopen("horsed.in","r",stdin);
	freopen("horsed.out","w",stdout);
    scanf("%d%d%d%d",&xp,&yp,&xs,&ys);
    a=ABS(xp-xs),b=ABS(yp-ys);
    if(a>50&&b>50) flag=true,a-=20,b-=20;
    if(flag){
        Update(0,a>>1);Update(a,0);Update(0,b);Update(b>>1,0);Update(((b<<1)-a)/3,((a<<1)-b)/3);
        a-=f1+(f2<<1),b-=(f1<<1)+f2;Ans=f1+f2;
    }
    if(a>b&&a>20) Ans+=(((a-20)>>2)-1)<<1,a-=(((a-20)>>2)-1)<<2;
    else if(b>20) Ans+=(((b-20)>>2)-1)<<1,b-=(((b-20)>>2)-1)<<2;
    if(flag) a+=20,b+=20;
    spfa();
    printf("%d",Ans);
    return 0;
}