zoukankan      html  css  js  c++  java
  • [HNOI2006]马步距离

    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


    首先想到(A^*),但是不知道能不能过。。。而且(A^*)基本没写过。。。

    我们换种想法,如果说两点之间差距很大的话,我们是可以贪心跳过去的

    距离较小的时候,我们就可以直接bfs搜索了,然后这题就过了。。。

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int frd(){
    	int x=0,f=1;char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)    putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e2;
    const int dx[8]={-2,-2,-1,-1,1,1,2,2};
    const int dy[8]={-1,1,-2,2,-2,2,-1,1};
    int dis[N+10][N+10];
    struct S1{
    	int x,y;
    	void insert(int _x,int _y){x=_x,y=_y;}
    }h[N*N+10];
    bool in_map(int x,int y){return x>0&&y>0&&x<=100&&y<=100;}
    void bfs(int x,int y){
    	int head=1,tail=1;
    	memset(dis,255,sizeof(dis));
    	h[head].insert(x,y),dis[x][y]=0;
    	for (;head<=tail;head++){
    		int Nx=h[head].x,Ny=h[head].y;
    		for (int k=0;k<8;k++){
    			int tx=Nx+dx[k],ty=Ny+dy[k];
    			if (in_map(tx,ty)&&!~dis[tx][ty]){
    				dis[tx][ty]=dis[Nx][Ny]+1;
    				h[++tail].insert(tx,ty);
    			}
    		}
    	}
    }
    int main(){
    	int ox=read(),oy=read(),ex=read(),ey=read(),Ans=0;
    	int x=abs(ox-ex),y=abs(oy-ey);
    	while (x+y>50){
    		if (x<y)	swap(x,y);
    		if (x-4>y<<1)	x-=4;
    		else	x-=4,y-=2;
    		Ans+=2;
    	}
    	x+=50,y+=50;
    	bfs(x,y);
    	printf("%d
    ",Ans+dis[50][50]);
    	return 0;
    }
    
  • 相关阅读:
    常用知识点集合
    LeetCode 66 Plus One
    LeetCode 88 Merge Sorted Array
    LeetCode 27 Remove Element
    LeetCode 26 Remove Duplicates from Sorted Array
    LeetCode 448 Find All Numbers Disappeared in an Array
    LeetCode 219 Contains Duplicate II
    LeetCode 118 Pascal's Triangle
    LeetCode 119 Pascal's Triangle II
    LeetCode 1 Two Sum
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9949272.html
Copyright © 2011-2022 走看看