HDU 3766 Knight‘s Trip(假的搜索题目)

传送门
Problem Description
In chess, each move of a knight consists of moving by two squares horizontally and one square vertically, or by one square horizontally and two squares vertically. A knight making one move from location (0,0) of an infinite chess board would end up at one of the following eight locations: (1,2), (-1,2), (1,-2), (-1,-2), (2,1), (-2,1), (2,-1), (-2,-1).

Starting from location (0,0), what is the minimum number of moves required for a knight to get to some other arbitrary location (x,y)?

Input
Each line of input contains two integers x and y, each with absolute value at most one billion. The integers designate a location (x,y) on the infinite chess board. The final line contains the word END.

Output
For each location in the input, output a line containing one integer, the minimum number of moves required for a knight to move from (0,0) to (x, y).

Sample Input

1 2
2 4
END

Sample Output

1
2

题意: 同象棋中马的行动方式,从起点出发,每次移动可以横向移动一个单位、纵向移动两个单位,或是横向移动两个单位、纵向移动一个单位,问到达一个目的地所需要花费的最短步数。
题解: 数据实在实在是太大了,不可能用dfs或bfs解决,而且图中也没有障碍,不需要用搜索的办法解决。其实就是一道思维题。下面代码中的公式,大部分人是通过打表的方式总结出来的。这个公式的解释吧,我向我的同学面对面解释也花费了一番功夫,所以很难用文字的方式再现(是我菜)。

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1e9+1;

int a, b;
char str[12];
int main(){
    while(~scanf("%s", str)){
        if(str[0]=='E')    break;
        sscanf(str, "%d", &a);//读取字符串中的数值赋给a
        scanf("%d", &b);

        a = abs(a), b = abs(b);//把所有目的地统一集中在第一象限来处理
        if(a > b)    swap(a, b);//集中到b=x直线的下方处理

        int ans = 0;
        if(b <= 2*a){
			if(a==1 && b==1)    ans = 2;
            else if(a==2 && b==2)    ans = 4;
            else    ans = (a + b) / 3 + (a + b) % 3;//对不起我没办法用文字的方式解释其中的数学规律,如果有能力可以尝试用打表的方式去总结。
        }else{
            ans = a;
            int c = (b - 2 * a) % 4;
            ans += c;
            ans += (b - 2 * a - c) / 2;
            if(b==1&&a==0)    ans = 3;
        }
        printf("%d\n", ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值